mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
CtrlCore: Cocoa font features (RenderCharSys, GetData), Draw: Font caching optimized, Core: FoldHash function
git-svn-id: svn://ultimatepp.org/upp/trunk@12177 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
8b045bc99d
commit
5a44eeb5a7
12 changed files with 137 additions and 29 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,9 @@ struct CocoTop;
|
|||
struct MMCtrl;
|
||||
struct MMImp;
|
||||
|
||||
#define GUIPLATFORM_CTRL_TOP_DECLS CocoTop *coco = NULL; One<DrawDragRectInfo> dr;
|
||||
#define GUIPLATFORM_CTRL_TOP_DECLS \
|
||||
CocoTop *coco = NULL; \
|
||||
One<DrawDragRectInfo> dr; \
|
||||
|
||||
#define GUIPLATFORM_CTRL_DECLS_INCLUDE <CtrlCore/CocoCtrl.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Upp::TopWindow *>(~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()
|
||||
|
|
|
|||
|
|
@ -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<CTFontDescriptorRef> fd = CTFontCopyFontDescriptor(ctfont);
|
||||
CFRef<CFURLRef> url = (CFURLRef)CTFontDescriptorCopyAttribute(fd, kCTFontURLAttribute);
|
||||
CFRef<CFStringRef> 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<FaceInfo> 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<CGPathRef> 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,
|
||||
|
|
|
|||
|
|
@ -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<TopWindow *>(ctrl);
|
||||
if(tw && ctrl->top && ctrl->top->placefocus) {
|
||||
tw->PlaceFocus();
|
||||
ctrl->top->placefocus = false;
|
||||
}*/
|
||||
}
|
||||
|
||||
static void ResignKey(Upp::Ctrl *ctrl)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//$ class TopWindow {
|
||||
protected:
|
||||
friend struct MMImp;
|
||||
|
||||
dword GetMMStyle() const;
|
||||
|
||||
virtual void MMClose() { WhenClose(); }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
Ptr<Ctrl> Ctrl::eventCtrl;
|
||||
Ptr<Ctrl> Ctrl::mouseCtrl;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
String TopWindow::GetDesc() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue