diff --git a/uppsrc/Core/Ops.h b/uppsrc/Core/Ops.h index 377a2e805..a41962e39 100644 --- a/uppsrc/Core/Ops.h +++ b/uppsrc/Core/Ops.h @@ -283,3 +283,8 @@ int fast_memcmp(const char *a, const char *b, size_t len) return memcmp(a, b, len); } #endif + +inline dword FoldHash(dword h) +{ + return h - SwapEndian32((dword)h); +} diff --git a/uppsrc/CtrlCore/Coco.h b/uppsrc/CtrlCore/Coco.h index 7ac82c432..4abed8885 100644 --- a/uppsrc/CtrlCore/Coco.h +++ b/uppsrc/CtrlCore/Coco.h @@ -153,7 +153,9 @@ struct CocoTop; struct MMCtrl; struct MMImp; -#define GUIPLATFORM_CTRL_TOP_DECLS CocoTop *coco = NULL; One dr; +#define GUIPLATFORM_CTRL_TOP_DECLS \ + CocoTop *coco = NULL; \ + One dr; \ #define GUIPLATFORM_CTRL_DECLS_INCLUDE diff --git a/uppsrc/CtrlCore/CocoCreate.mm b/uppsrc/CtrlCore/CocoCreate.mm index 2b1b96691..9f6447c01 100644 --- a/uppsrc/CtrlCore/CocoCreate.mm +++ b/uppsrc/CtrlCore/CocoCreate.mm @@ -14,11 +14,16 @@ @implementation CocoWindow +- (void)becomeKeyWindow { + [super becomeKeyWindow]; +} + - (BOOL)canBecomeKeyWindow { return active && ctrl && ctrl->IsEnabled(); } - (BOOL)canBecomeMainWindow { + LLOG("canBecomeMainWindow " << Upp::Name(ctrl) << ", owner " << Upp::Name(ctrl->GetOwner())); return active && ctrl && ctrl->IsEnabled() && dynamic_cast(~ctrl) && !ctrl->GetOwner(); } @@ -81,32 +86,33 @@ NSRect DesktopRect(const Upp::Rect& r) void Upp::Ctrl::Create(Ctrl *owner, dword style, bool active) { + top = new Top; + top->coco = new CocoTop; + top->coco->owner = owner; + NSRect frame = DesktopRect(GetRect()); - CocoWindow *window = [[CocoWindow alloc] initWithContentRect:frame styleMask: style backing:NSBackingStoreBuffered defer:false]; + top->coco->window = window; + if(owner && owner->top && owner->top->coco) + [owner->top->coco->window addChildWindow:window ordered:NSWindowAbove]; + window->ctrl = this; window->active = active; window.backgroundColor = nil; CocoView *view = [[[CocoView alloc] initWithFrame:frame] autorelease]; view->ctrl = this; + top->coco->view = view; [window setContentView:view]; [window setDelegate:view]; [window setAcceptsMouseMovedEvents:YES]; [window makeFirstResponder:view]; [window makeKeyAndOrderFront:view]; - top = new Top; - top->coco = new CocoTop; - top->coco->window = window; - top->coco->view = view; - top->coco->owner = owner; MMCtrl::SyncRect(view); isopen = true; mmtopctrl.Add(this); - if(owner && owner->top && owner->top->coco) - [owner->top->coco->window addChildWindow:window ordered:NSWindowAbove]; } void Upp::Ctrl::WndDestroy() @@ -159,8 +165,27 @@ bool Upp::Ctrl::IsWndOpen() const { void Upp::Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) { - Create(owner, NSWindowStyleMaskBorderless, false); + Create(owner, NSWindowStyleMaskBorderless, 0*activate); popup = true; + if(activate) { + #if 0 + NSWindow *window = top->coco->window; + [window setBackgroundColor:[NSColor clearColor]]; + [window setOpaque:NO]; + [window setStyleMask:NSResizableWindowMask | NSTitledWindowMask | NSFullSizeContentViewWindowMask]; + [window setMovableByWindowBackground:YES]; + [window setTitlebarAppearsTransparent:YES]; + [window setTitleVisibility:NSWindowTitleHidden]; + [window setShowsToolbarButton:NO]; + [window standardWindowButton:NSWindowFullScreenButton].hidden = YES; + [window standardWindowButton:NSWindowMiniaturizeButton].hidden = YES; + [window standardWindowButton:NSWindowCloseButton].hidden = YES; + [window standardWindowButton:NSWindowZoomButton].hidden = YES; + [window makeKeyWindow]; + // [window setHasShadow:YES]; + #endif + ActivateWnd(); + } } Upp::dword Upp::TopWindow::GetMMStyle() const @@ -182,8 +207,12 @@ void Upp::TopWindow::Open(Ctrl *owner) : GetPrimaryWorkArea()) .CenterRect(GetRect().GetSize())); Create(owner, GetMMStyle(), true); + ActivateWnd(); SyncCaption(); SyncSizeHints(); + PlaceFocus(); +// if(top) +// top->placefocus = true; } void Upp::TopWindow::Open() diff --git a/uppsrc/CtrlCore/CocoDrawText.mm b/uppsrc/CtrlCore/CocoDrawText.mm index 2ef6b8b80..07c412b4c 100644 --- a/uppsrc/CtrlCore/CocoDrawText.mm +++ b/uppsrc/CtrlCore/CocoDrawText.mm @@ -52,6 +52,14 @@ CTFontRef CT_Font(Font fnt) return e.ctfont; } +CGGlyph GetCharGlyph(CTFontRef ctfont, int chr) +{ + CGGlyph glyph_index; + UniChar h = chr; + CTFontGetGlyphsForCharacters(ctfont, &h, &glyph_index, 1); + return glyph_index; +} + GlyphInfo GetGlyphInfoSys(CTFontRef ctfont, int chr) { GlyphInfo gi; @@ -59,9 +67,7 @@ GlyphInfo GetGlyphInfoSys(CTFontRef ctfont, int chr) gi.width = 0x8000; if(ctfont) { LTIMING("GetGlyphInfoSys 2"); - CGGlyph glyph_index; - UniChar h = chr; - CTFontGetGlyphsForCharacters(ctfont, &h, &glyph_index, 1); + CGGlyph glyph_index = GetCharGlyph(ctfont, chr); if(glyph_index) { CGSize advance; CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, &glyph_index, &advance, 1); @@ -100,10 +106,15 @@ CommonFontInfo GetFontInfoSys(Font font) fi.default_char = '?'; fi.fixedpitch = CTFontGetSymbolicTraits(ctfont) & kCTFontMonoSpaceTrait; fi.ttf = true; -// TODO: PATH for data -// if(path.GetCount() < 250) -// strcpy(fi.path, ~path); -// else + + CFRef fd = CTFontCopyFontDescriptor(ctfont); + CFRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fd, kCTFontURLAttribute); + CFRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); + String p = ToString(path); + + if(p.GetCount() < 250) + strcpy(fi.path, ~p); + else *fi.path = 0; } return fi; @@ -156,13 +167,53 @@ Vector GetAllFacesSys() } String GetFontDataSys(Font font) -{ // TODO! CFUrl? - return Null; +{ + return LoadFile(font.Fi().path); } -void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt) +struct sCGPathTarget { + double x, y; + FontGlyphConsumer *sw; +}; + +static void convertCGPathToQPainterPath(void *info, const CGPathElement *e) { - // TODO! + auto t = (sCGPathTarget *)info; + switch(e->type) { + case kCGPathElementMoveToPoint: + t->sw->Move(Pointf(e->points[0].x + t->x, e->points[0].y + t->y)); + break; + case kCGPathElementAddLineToPoint: + t->sw->Line(Pointf(e->points[0].x + t->x, e->points[0].y + t->y)); + break; + case kCGPathElementAddQuadCurveToPoint: + t->sw->Quadratic(Pointf(e->points[0].x + t->x, e->points[0].y + t->y), + Pointf(e->points[1].x + t->x, e->points[1].y + t->y)); + break; + case kCGPathElementAddCurveToPoint: + t->sw->Cubic(Pointf(e->points[0].x + t->x, e->points[0].y + t->y), + Pointf(e->points[1].x + t->x, e->points[1].y + t->y), + Pointf(e->points[2].x + t->x, e->points[2].y + t->y)); + break; + case kCGPathElementCloseSubpath: + t->sw->Close(); + break; + } +} + +void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int chr, Font font) +{ + CGAffineTransform cgMatrix = CGAffineTransformIdentity; + cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); + + CTFontRef ctfont = CT_Font(font); + CGGlyph glyph_index = GetCharGlyph(ctfont, chr); + CFRef cgpath = CTFontCreatePathForGlyph(ctfont, glyph_index, &cgMatrix); + sCGPathTarget t; + t.x = x; + t.y = y + font.GetAscent(); + t.sw = &sw; + CGPathApply(cgpath, &t, convertCGPathToQPainterPath); } void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, diff --git a/uppsrc/CtrlCore/CocoProc.mm b/uppsrc/CtrlCore/CocoProc.mm index 085c16240..00f6f12fd 100644 --- a/uppsrc/CtrlCore/CocoProc.mm +++ b/uppsrc/CtrlCore/CocoProc.mm @@ -68,6 +68,7 @@ struct MMImp { view->ctrl->DispatchMouse(event, p, 120 * sgn(zd)); return false; } + static bool MouseDownEvent(CocoView *view, NSEvent *e, int button) { static int clicktime = msecs() - 100000; @@ -146,7 +147,13 @@ struct MMImp { static void BecomeKey(Upp::Ctrl *ctrl) { + LLOG("Become key " << Upp::Name(ctrl)); ctrl->ActivateWnd(); +/* auto tw = dynamic_cast(ctrl); + if(tw && ctrl->top && ctrl->top->placefocus) { + tw->PlaceFocus(); + ctrl->top->placefocus = false; + }*/ } static void ResignKey(Upp::Ctrl *ctrl) diff --git a/uppsrc/CtrlCore/CocoTop.h b/uppsrc/CtrlCore/CocoTop.h index 23a271860..d98c7105e 100644 --- a/uppsrc/CtrlCore/CocoTop.h +++ b/uppsrc/CtrlCore/CocoTop.h @@ -1,5 +1,7 @@ //$ class TopWindow { protected: + friend struct MMImp; + dword GetMMStyle() const; virtual void MMClose() { WhenClose(); } diff --git a/uppsrc/CtrlCore/CtrlMouse.cpp b/uppsrc/CtrlCore/CtrlMouse.cpp index 8d10c272a..2eab0afee 100644 --- a/uppsrc/CtrlCore/CtrlMouse.cpp +++ b/uppsrc/CtrlCore/CtrlMouse.cpp @@ -2,7 +2,7 @@ namespace Upp { -#define LLOG(x) // DLOG(x) +#define LLOG(x) // DLOG(x) Ptr Ctrl::eventCtrl; Ptr Ctrl::mouseCtrl; diff --git a/uppsrc/CtrlCore/TopWindow.cpp b/uppsrc/CtrlCore/TopWindow.cpp index 4100f604c..329177229 100644 --- a/uppsrc/CtrlCore/TopWindow.cpp +++ b/uppsrc/CtrlCore/TopWindow.cpp @@ -2,7 +2,7 @@ namespace Upp { -#define LLOG(x) // DLOG(x) +#define LLOG(x) // DLOG(x) String TopWindow::GetDesc() const { diff --git a/uppsrc/CtrlCore/cocotodo.txt b/uppsrc/CtrlCore/cocotodo.txt index c14421418..195b8d9e6 100644 --- a/uppsrc/CtrlCore/cocotodo.txt +++ b/uppsrc/CtrlCore/cocotodo.txt @@ -1,5 +1,7 @@ sooner: +- reference/Reports - missing text + - opening FindInFiles, then selecting folder - pushing buttons does not exit dialog - package organizer initial size too small diff --git a/uppsrc/CtrlLib/MenuBar.cpp b/uppsrc/CtrlLib/MenuBar.cpp index d75e0b214..1de42ffea 100644 --- a/uppsrc/CtrlLib/MenuBar.cpp +++ b/uppsrc/CtrlLib/MenuBar.cpp @@ -24,7 +24,11 @@ BorderFrame& XPMenuFrame() CtrlFrame& MenuFrame() { +#ifdef PLATFORM_COCOA + return NullFrame(); +#else return GUI_GlobalStyle() >= GUISTYLE_XP ? (CtrlFrame&)XPMenuFrame() : (CtrlFrame&)OutsetFrame(); +#endif } CH_STYLE(MenuBar, Style, StyleDefault) @@ -447,6 +451,7 @@ void MenuBar::SetActiveSubmenu(MenuBar *sm, Ctrl *item) void MenuBar::SubmenuClose() { + LLOG("SubmenuClose"); if(parentmenu && parentmenu->GetActiveSubmenu() == this) parentmenu->SetActiveSubmenu(NULL, NULL); else { diff --git a/uppsrc/Draw/Font.cpp b/uppsrc/Draw/Font.cpp index 83e06b320..1244f6d9c 100644 --- a/uppsrc/Draw/Font.cpp +++ b/uppsrc/Draw/Font.cpp @@ -391,11 +391,16 @@ struct CharEntry { CharEntry fc_cache_global[4093]; +inline dword GlyphHash(Font font, int chr) +{ + return FoldHash(CombineHash(font.GetHashValue(), chr)); +} + bool IsNormal(Font font, int chr) { Mutex::Lock __(sFontLock); font.RealizeStd(); - CharEntry& e = fc_cache_global[CombineHash(font.GetHashValue(), chr) % 4093]; + CharEntry& e = fc_cache_global[GlyphHash(font, chr) % 4093]; if(e.font == font.AsInt64() || e.chr == chr) return e.info.IsNormal(); return GetGlyphInfoSys(font, chr).IsNormal(); @@ -433,7 +438,7 @@ thread__ CharEntry fc_cache[512]; GlyphInfo GetGlyphInfo(Font font, int chr) { font.RealizeStd(); - unsigned hash = CombineHash(font.GetHashValue(), chr); + unsigned hash = GlyphHash(font, chr); CharEntry& e = fc_cache[hash & 511]; if(e.font != font.AsInt64() || e.chr != chr) e = GetGlyphEntry(font, chr, hash); @@ -499,12 +504,12 @@ struct FontEntry { int64 font; }; -thread__ FontEntry fi_cache[64]; +thread__ FontEntry fi_cache[63]; const CommonFontInfo& GetFontInfo(Font font) { font.RealizeStd(); - unsigned hash = font.GetHashValue() & 63; + unsigned hash = FoldHash(font.GetHashValue()) % 63; FontEntry& e = fi_cache[hash]; if(e.font != font.AsInt64()) { Mutex::Lock __(sFontLock); diff --git a/uppsrc/Draw/FontFc.cpp b/uppsrc/Draw/FontFc.cpp index 5082015b4..5096cb99a 100644 --- a/uppsrc/Draw/FontFc.cpp +++ b/uppsrc/Draw/FontFc.cpp @@ -357,9 +357,9 @@ bool RenderOutline(const FT_Outline& outline, FontGlyphConsumer& path, double xx FT_Vector vec1, vec2; if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) return false; - vec1.x = point[0].x; + vec1.x = point[0].x; vec1.y = point[0].y; - vec2.x = point[1].x; + vec2.x = point[1].x; vec2.y = point[1].y; point += 2; tags += 2;