From a51abfffc127e3c7be86a3755a3d820d05002cdf Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Mon, 16 Nov 2015 21:29:32 +0300 Subject: [PATCH] mac osx cocoa support prototype --- .../derelictcocoatest-monod-osx.dproj | 32 +- .../src/cocoatest.d | 648 ++++++++++++++++++ examples/example1/example1-monod-osx.dproj | 5 +- src/dlangui/platforms/common/platform.d | 20 +- src/dlangui/widgets/styles.d | 4 +- 5 files changed, 680 insertions(+), 29 deletions(-) diff --git a/examples/derelictcocoatest-monod-osx/derelictcocoatest-monod-osx.dproj b/examples/derelictcocoatest-monod-osx/derelictcocoatest-monod-osx.dproj index 6c640c5e..67b8eda5 100644 --- a/examples/derelictcocoatest-monod-osx/derelictcocoatest-monod-osx.dproj +++ b/examples/derelictcocoatest-monod-osx/derelictcocoatest-monod-osx.dproj @@ -2,7 +2,7 @@ Debug - AnyCPU + x64 {1F050D82-5245-4B51-A554-473194EA0DE9} DMD2 true @@ -26,17 +26,6 @@ - - true - bin\Debug - obj/Debug - false - false - derelictcocoatest-monod-osx - Executable - true - 0 - bin\Release obj/Release @@ -58,6 +47,25 @@ true 0 + + true + bin\Debug + + + USE_SDL + USE_OPENGL + USE_FREETYPE + EmbedStandardResources + + + obj/Debug + false + false + derelictcocoatest-monod-osx + Executable + true + 0 + diff --git a/examples/derelictcocoatest-monod-osx/src/cocoatest.d b/examples/derelictcocoatest-monod-osx/src/cocoatest.d index a88f6db9..c19a4805 100644 --- a/examples/derelictcocoatest-monod-osx/src/cocoatest.d +++ b/examples/derelictcocoatest-monod-osx/src/cocoatest.d @@ -1,8 +1,14 @@ module cocoatest; +version(OSX): import derelict.cocoa; import dlangui.core.logger; +import dlangui.core.types; +import dlangui.core.events; +import std.uuid; +import core.stdc.stdlib; +import std.string; void main(string[] args) { @@ -35,9 +41,651 @@ void main(string[] args) NSView parentView; parentView = window.contentView(); + + Log.i("parentView=", parentView); NSApp.activateIgnoringOtherApps(YES); + +// string uuid = randomUUID().toString(); +// DlanguiCocoaView.customClassName = "DlanguiCocoaView_" ~ uuid; +// DlanguiCocoaView.registerSubclass(); +// +// _view = DlanguiCocoaView.alloc(); +// _view.initialize(this, width, height); +// +// parentView.addSubview(_view); + + NSApp.run(); DerelictCocoa.unload(); } + +interface IWindowListener { + void onMouseWheel(int x, int y, int deltaX, int deltaY, MouseState state); + void onKeyDown(uint key); + void onKeyUp(uint key); + void onMouseMove(int x, int y, int deltaX, int deltaY, + MouseState mouseState); + void onMouseRelease(int x, int y, MouseButton mb, MouseState mouseState); + void onMouseClick(int x, int y, MouseButton mb, bool isDoubleClick, MouseState mouseState); + void recomputeDirtyAreas(); + void onResized(int width, int height); + void onAnimate(double dt, double time); + Rect getDirtyRectangle(); +} + +struct MouseState { + bool leftButtonDown; + bool rightButtonDown; + bool middleButtonDown; + bool ctrlPressed; + bool shiftPressed; + bool altPressed; +} + +enum MouseButton : int { + left, + right, + middle +} + +final class CocoaWindow +{ +private: + IWindowListener _listener; + + // Stays null in the case of a plugin, but exists for a stand-alone program + // For testing purpose. + NSWindow _cocoaWindow = null; + NSApplication _cocoaApplication; + + NSColorSpace _nsColorSpace; + CGColorSpaceRef _cgColorSpaceRef; + NSData _imageData; + NSString _logFormatStr; + + DPlugCustomView _view = null; + + bool _terminated = false; + + int _lastMouseX, _lastMouseY; + bool _firstMouseMove = true; + + int _width; + int _height; + + ubyte* _buffer = null; + + uint _timeAtCreationInMs; + uint _lastMeasturedTimeInMs; + bool _dirtyAreasAreNotYetComputed; + +public: + + this(void* parentWindow, IWindowListener listener, int width, int height) + { + _listener = listener; + + DerelictCocoa.load(); + NSApplicationLoad(); // to use Cocoa in Carbon applications + bool parentViewExists = parentWindow !is null; + NSView parentView; + if (!parentViewExists) + { + // create a NSWindow to hold our NSView + _cocoaApplication = NSApplication.sharedApplication; + _cocoaApplication.setActivationPolicy(NSApplicationActivationPolicyRegular); + + NSWindow window = NSWindow.alloc(); + window.initWithContentRect(NSMakeRect(100, 100, width, height), + NSBorderlessWindowMask, NSBackingStoreBuffered, NO); + window.makeKeyAndOrderFront(); + + parentView = window.contentView(); + + _cocoaApplication.activateIgnoringOtherApps(YES); + } + else + parentView = NSView(cast(id)parentWindow); + + + + _width = 0; + _height = 0; + + _nsColorSpace = NSColorSpace.sRGBColorSpace(); + // hopefully not null else the colors will be brighter + _cgColorSpaceRef = _nsColorSpace.CGColorSpace(); + + _logFormatStr = NSString.stringWith("%@"); + + _timeAtCreationInMs = getTimeMs(); + _lastMeasturedTimeInMs = _timeAtCreationInMs; + + _dirtyAreasAreNotYetComputed = true; + + string uuid = randomUUID().toString(); + DPlugCustomView.customClassName = "DPlugCustomView_" ~ uuid; + DPlugCustomView.registerSubclass(); + + _view = DPlugCustomView.alloc(); + _view.initialize(this, width, height); + + parentView.addSubview(_view); + + if (_cocoaApplication) + _cocoaApplication.run(); + + + } + + ~this() + { + if (_view) + { + //debug ensureNotInGC("CocoaWindow"); + _terminated = true; + + { + _view.killTimer(); + } + + _view.removeFromSuperview(); + _view.release(); + _view = DPlugCustomView(null); + + DPlugCustomView.unregisterSubclass(); + + if (_buffer != null) + { + free(_buffer); + _buffer = null; + } + + DerelictCocoa.unload(); + } + } + + // Implements IWindow + void waitEventAndDispatch() + { + assert(false); // not implemented in Cocoa, since we don't have a NSWindow + } + + bool terminated() + { + return _terminated; + } + + void debugOutput(string s) + { + import core.stdc.stdio; + fprintf(stderr, toStringz(s)); + } + + uint getTimeMs() + { + return cast(uint)(NSDate.timeIntervalSinceReferenceDate() * 1000.0); + } + +private: + + MouseState getMouseState(NSEvent event) + { + // not working + MouseState state; + uint pressedMouseButtons = event.pressedMouseButtons(); + if (pressedMouseButtons & 1) + state.leftButtonDown = true; + if (pressedMouseButtons & 2) + state.rightButtonDown = true; + if (pressedMouseButtons & 4) + state.middleButtonDown = true; + + NSEventModifierFlags mod = event.modifierFlags(); + if (mod & NSControlKeyMask) + state.ctrlPressed = true; + if (mod & NSShiftKeyMask) + state.shiftPressed = true; + if (mod & NSAlternateKeyMask) + state.altPressed = true; + + return state; + } + + void handleMouseWheel(NSEvent event) + { + int deltaX = cast(int)(0.5 + 10 * event.deltaX); + int deltaY = cast(int)(0.5 + 10 * event.deltaY); + Point mousePos = getMouseXY(_view, event, _height); + _listener.onMouseWheel(mousePos.x, mousePos.y, deltaX, deltaY, getMouseState(event)); + } + + void handleKeyEvent(NSEvent event, bool released) + { + uint keyCode = event.keyCode(); + uint key; + switch (keyCode) + { + case kVK_ANSI_Keypad0: key = KeyCode.KEY_0; break; + case kVK_ANSI_Keypad1: key = KeyCode.KEY_1; break; + case kVK_ANSI_Keypad2: key = KeyCode.KEY_2; break; + case kVK_ANSI_Keypad3: key = KeyCode.KEY_3; break; + case kVK_ANSI_Keypad4: key = KeyCode.KEY_4; break; + case kVK_ANSI_Keypad5: key = KeyCode.KEY_5; break; + case kVK_ANSI_Keypad6: key = KeyCode.KEY_6; break; + case kVK_ANSI_Keypad7: key = KeyCode.KEY_7; break; + case kVK_ANSI_Keypad8: key = KeyCode.KEY_8; break; + case kVK_ANSI_Keypad9: key = KeyCode.KEY_9; break; + case kVK_Return: key = KeyCode.RETURN; break; + case kVK_Escape: key = KeyCode.ESCAPE; break; + case kVK_LeftArrow: key = KeyCode.LEFT; break; + case kVK_RightArrow: key = KeyCode.RIGHT; break; + case kVK_DownArrow: key = KeyCode.DOWN; break; + case kVK_UpArrow: key = KeyCode.UP; break; + default: key = 0; + } + + if (released) + _listener.onKeyDown(key); + else + _listener.onKeyUp(key); + } + + void handleMouseMove(NSEvent event) + { + Point mousePos = getMouseXY(_view, event, _height); + + if (_firstMouseMove) + { + _firstMouseMove = false; + _lastMouseX = mousePos.x; + _lastMouseY = mousePos.y; + } + + _listener.onMouseMove(mousePos.x, mousePos.y, mousePos.x - _lastMouseX, mousePos.y - _lastMouseY, + getMouseState(event)); + + _lastMouseX = mousePos.x; + _lastMouseY = mousePos.y; + } + + void handleMouseClicks(NSEvent event, MouseButton mb, bool released) + { + Point mousePos = getMouseXY(_view, event, _height); + + if (released) + _listener.onMouseRelease(mousePos.x, mousePos.y, mb, getMouseState(event)); + else + { + int clickCount = event.clickCount(); + bool isDoubleClick = clickCount >= 2; + _listener.onMouseClick(mousePos.x, mousePos.y, mb, isDoubleClick, getMouseState(event)); + } + } + + enum scanLineAlignment = 4; // could be anything + + // given a width, how long in bytes should scanlines be + int byteStride(int width) + { + int widthInBytes = width * 4; + return (widthInBytes + (scanLineAlignment - 1)) & ~(scanLineAlignment-1); + } + + void drawRect(NSRect rect) + { + NSGraphicsContext nsContext = NSGraphicsContext.currentContext(); + + CIContext ciContext = nsContext.getCIContext(); + + // update internal buffers in case of startup/resize + { + NSRect boundsRect = _view.bounds(); + int width = cast(int)(boundsRect.size.width); // truncating down the dimensions of bounds + int height = cast(int)(boundsRect.size.height); + updateSizeIfNeeded(width, height); + } + + // The first drawRect callback occurs before the timer triggers. + // But because recomputeDirtyAreas() wasn't called before there is nothing to draw. + // Hence, do it. + if (_dirtyAreasAreNotYetComputed) + { + _dirtyAreasAreNotYetComputed = false; + _listener.recomputeDirtyAreas(); + } + + // draw buffers +// ImageRef!RGBA wfb; +// wfb.w = _width; +// wfb.h = _height; +// wfb.pitch = byteStride(_width); +// wfb.pixels = cast(RGBA*)_buffer; +// _listener.onDraw(wfb, WindowPixelFormat.ARGB8); + + + size_t sizeNeeded = byteStride(_width) * _height; + _imageData = NSData.dataWithBytesNoCopy(_buffer, sizeNeeded, false); + + CIImage image = CIImage.imageWithBitmapData(_imageData, + byteStride(_width), + CGSize(_width, _height), + kCIFormatARGB8, + _cgColorSpaceRef); + + ciContext.drawImage(image, rect, rect); + } + + /// Returns: true if window size changed. + bool updateSizeIfNeeded(int newWidth, int newHeight) + { + // only do something if the client size has changed + if ( (newWidth != _width) || (newHeight != _height) ) + { + // Extends buffer + if (_buffer != null) + { + free(_buffer); + _buffer = null; + } + + size_t sizeNeeded = byteStride(newWidth) * newHeight; + _buffer = cast(ubyte*) malloc(sizeNeeded); + _width = newWidth; + _height = newHeight; + _listener.onResized(_width, _height); + return true; + } + else + return false; + } + + void doAnimation() + { + uint now = getTimeMs(); + double dt = (now - _lastMeasturedTimeInMs) * 0.001; + double time = (now - _timeAtCreationInMs) * 0.001; // hopefully no plug-in will be open more than 49 days + _lastMeasturedTimeInMs = now; + _listener.onAnimate(dt, time); + } + + void onTimer() + { + // Deal with animation + doAnimation(); + + _listener.recomputeDirtyAreas(); + _dirtyAreasAreNotYetComputed = false; + Rect dirtyRect = _listener.getDirtyRectangle(); + if (!dirtyRect.empty()) + { + + NSRect boundsRect = _view.bounds(); + int height = cast(int)(boundsRect.size.height); + NSRect r = NSMakeRect(dirtyRect.left, + height - dirtyRect.top - dirtyRect.height, + dirtyRect.width, + dirtyRect.height); + _view.setNeedsDisplayInRect(r); + } + } +} + +struct DPlugCustomView +{ + // This class uses a unique class name for each plugin instance + static string customClassName = null; + + NSView parent; + alias parent this; + + // create from an id + this (id id_) + { + this._id = id_; + } + + /// Allocates, but do not init + static DPlugCustomView alloc() + { + alias fun_t = extern(C) id function (id obj, SEL sel); + return DPlugCustomView( (cast(fun_t)objc_msgSend)(getClassID(), sel!"alloc") ); + } + + static Class getClass() + { + return cast(Class)( getClassID() ); + } + + static id getClassID() + { + assert(customClassName !is null); + return objc_getClass(customClassName); + } + +private: + + CocoaWindow _window; + NSTimer _timer = null; + + void initialize(CocoaWindow window, int width, int height) + { + // Warning: taking this address is fishy since DPlugCustomView is a struct and thus could be copied + // we rely on the fact it won't :| + void* thisPointer = cast(void*)(&this); + object_setInstanceVariable(_id, "this", thisPointer); + + this._window = window; + + NSRect r = NSRect(NSPoint(0, 0), NSSize(width, height)); + initWithFrame(r); + + _timer = NSTimer.timerWithTimeInterval(1 / 60.0, this, sel!"onTimer:", null, true); + NSRunLoop.currentRunLoop().addTimer(_timer, NSRunLoopCommonModes); + } + + static Class clazz; + + static void registerSubclass() + { + clazz = objc_allocateClassPair(cast(Class) lazyClass!"NSView", toStringz(customClassName), 0); + + class_addMethod(clazz, sel!"keyDown:", cast(IMP) &keyDown, "v@:@"); + class_addMethod(clazz, sel!"keyUp:", cast(IMP) &keyUp, "v@:@"); + class_addMethod(clazz, sel!"mouseDown:", cast(IMP) &mouseDown, "v@:@"); + class_addMethod(clazz, sel!"mouseUp:", cast(IMP) &mouseUp, "v@:@"); + class_addMethod(clazz, sel!"rightMouseDown:", cast(IMP) &rightMouseDown, "v@:@"); + class_addMethod(clazz, sel!"rightMouseUp:", cast(IMP) &rightMouseUp, "v@:@"); + class_addMethod(clazz, sel!"otherMouseDown:", cast(IMP) &otherMouseDown, "v@:@"); + class_addMethod(clazz, sel!"otherMouseUp:", cast(IMP) &otherMouseUp, "v@:@"); + class_addMethod(clazz, sel!"mouseMoved:", cast(IMP) &mouseMoved, "v@:@"); + class_addMethod(clazz, sel!"mouseDragged:", cast(IMP) &mouseMoved, "v@:@"); + class_addMethod(clazz, sel!"rightMouseDragged:", cast(IMP) &mouseMoved, "v@:@"); + class_addMethod(clazz, sel!"otherMouseDragged:", cast(IMP) &mouseMoved, "v@:@"); + class_addMethod(clazz, sel!"acceptsFirstResponder", cast(IMP) &acceptsFirstResponder, "b@:"); + class_addMethod(clazz, sel!"isOpaque", cast(IMP) &isOpaque, "b@:"); + class_addMethod(clazz, sel!"acceptsFirstMouse:", cast(IMP) &acceptsFirstMouse, "b@:@"); + class_addMethod(clazz, sel!"viewDidMoveToWindow", cast(IMP) &viewDidMoveToWindow, "v@:"); + class_addMethod(clazz, sel!"drawRect:", cast(IMP) &drawRect, "v@:" ~ encode!NSRect); + class_addMethod(clazz, sel!"onTimer:", cast(IMP) &onTimer, "v@:@"); + + // This ~ is to avoid a strange DMD ICE. Didn't succeed in isolating it. + class_addMethod(clazz, sel!("scroll" ~ "Wheel:") , cast(IMP) &scrollWheel, "v@:@"); + + // very important: add an instance variable for the this pointer so that the D object can be + // retrieved from an id + class_addIvar(clazz, "this", (void*).sizeof, (void*).sizeof == 4 ? 2 : 3, "^v"); + + objc_registerClassPair(clazz); + } + + static void unregisterSubclass() + { + // For some reason the class need to continue to exist, so we leak it + // objc_disposeClassPair(clazz); + // TODO: remove this crap + } + + void killTimer() + { + if (_timer) + { + _timer.invalidate(); + _timer = NSTimer(null); + } + } +} + +DPlugCustomView getInstance(id anId) +{ + // strange thing: object_getInstanceVariable definition is odd (void**) + // and only works for pointer-sized values says SO + void* thisPointer = null; + Ivar var = object_getInstanceVariable(anId, "this", &thisPointer); + assert(var !is null); + assert(thisPointer !is null); + return *cast(DPlugCustomView*)thisPointer; +} + +Point getMouseXY(NSView view, NSEvent event, int windowHeight) +{ + NSPoint mouseLocation = event.locationInWindow(); + mouseLocation = view.convertPoint(mouseLocation, NSView(null)); + int px = cast(int)(mouseLocation.x) - 2; + int py = windowHeight - cast(int)(mouseLocation.y) - 3; + return Point(px, py); +} + +// Overridden function gets called with an id, instead of the self pointer. +// So we have to get back the D class object address. +// Big thanks to Mike Ash (@macdev) +extern(C) +{ + void keyDown(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleKeyEvent(NSEvent(event), false); + } + + void keyUp(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleKeyEvent(NSEvent(event), true); + } + + void mouseDown(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleMouseClicks(NSEvent(event), MouseButton.left, false); + } + + void mouseUp(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleMouseClicks(NSEvent(event), MouseButton.left, true); + } + + void rightMouseDown(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleMouseClicks(NSEvent(event), MouseButton.right, false); + } + + void rightMouseUp(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleMouseClicks(NSEvent(event), MouseButton.right, true); + } + + void otherMouseDown(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + auto nsEvent = NSEvent(event); + if (nsEvent.buttonNumber == 2) + view._window.handleMouseClicks(nsEvent, MouseButton.middle, false); + } + + void otherMouseUp(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + auto nsEvent = NSEvent(event); + if (nsEvent.buttonNumber == 2) + view._window.handleMouseClicks(nsEvent, MouseButton.middle, true); + } + + void mouseMoved(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleMouseMove(NSEvent(event)); + } + + void scrollWheel(id self, SEL selector, id event) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.handleMouseWheel(NSEvent(event)); + } + + bool acceptsFirstResponder(id self, SEL selector) + { + return YES; + } + + bool acceptsFirstMouse(id self, SEL selector, id pEvent) + { + return YES; + } + + bool isOpaque(id self, SEL selector) + { + return YES; + } + + void viewDidMoveToWindow(id self, SEL selector) + { + DPlugCustomView view = getInstance(self); + NSWindow parentWindow = view.window(); + if (parentWindow) + { + parentWindow.makeFirstResponder(view); + parentWindow.setAcceptsMouseMovedEvents(true); + } + } + + void drawRect(id self, SEL selector, NSRect rect) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.drawRect(rect); + } + + void onTimer(id self, SEL selector, id timer) + { + //FPControl fpctrl; + //fpctrl.initialize(); + DPlugCustomView view = getInstance(self); + view._window.onTimer(); + } +} \ No newline at end of file diff --git a/examples/example1/example1-monod-osx.dproj b/examples/example1/example1-monod-osx.dproj index b7874e6c..f65fc79b 100644 --- a/examples/example1/example1-monod-osx.dproj +++ b/examples/example1/example1-monod-osx.dproj @@ -38,14 +38,13 @@ obj/Debug true - -Jviews -Jviews/res -Jviews/res/i18n -Jviews/res/mdpi -Jviews/res/hdpi --v + -Jviews -Jviews/res -Jviews/res/i18n -Jviews/res/mdpi -Jviews/res/hdpi false example1-monod-osx Executable true 0 - -v + false bin\Release diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 399f342d..7d46188e 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -1521,22 +1521,18 @@ version (Windows) { ft.registerFont("/Library/Fonts/Arial Bold.ttf", FontFamily.SansSerif, "Arial", false, FontWeight.Bold); ft.registerFont("/Library/Fonts/Arial Italic.ttf", FontFamily.SansSerif, "Arial", true, FontWeight.Normal); ft.registerFont("/Library/Fonts/Arial Bold Italic.ttf", FontFamily.SansSerif, "Arial", true, FontWeight.Bold); - ft.registerFont("/Library/Fonts/Arial Narrow.ttf", FontFamily.SansSerif, "Arial Narrow", false, FontWeight.Normal); - ft.registerFont("/Library/Fonts/Arial Narrow Bold.ttf", FontFamily.SansSerif, "Arial Narrow", false, FontWeight.Bold); - ft.registerFont("/Library/Fonts/Arial Narrow Italic.ttf", FontFamily.SansSerif, "Arial Narrow", true, FontWeight.Normal); - ft.registerFont("/Library/Fonts/Arial Narrow Bold Italic.ttf", FontFamily.SansSerif, "Arial Narrow", true, FontWeight.Bold); + //ft.registerFont("/Library/Fonts/Arial Narrow.ttf", FontFamily.SansSerif, "Arial Narrow", false, FontWeight.Normal); + //ft.registerFont("/Library/Fonts/Arial Narrow Bold.ttf", FontFamily.SansSerif, "Arial Narrow", false, FontWeight.Bold); + //ft.registerFont("/Library/Fonts/Arial Narrow Italic.ttf", FontFamily.SansSerif, "Arial Narrow", true, FontWeight.Normal); + //ft.registerFont("/Library/Fonts/Arial Narrow Bold Italic.ttf", FontFamily.SansSerif, "Arial Narrow", true, FontWeight.Bold); ft.registerFont("/Library/Fonts/Courier New.ttf", FontFamily.MonoSpace, "Courier New", false, FontWeight.Normal); ft.registerFont("/Library/Fonts/Courier New Bold.ttf", FontFamily.MonoSpace, "Courier New", false, FontWeight.Bold); ft.registerFont("/Library/Fonts/Courier New Italic.ttf", FontFamily.MonoSpace, "Courier New", true, FontWeight.Normal); ft.registerFont("/Library/Fonts/Courier New Bold Italic.ttf", FontFamily.MonoSpace, "Courier New", true, FontWeight.Bold); - ft.registerFont("/Library/Fonts/Georgia.ttf", FontFamily.SansSerif, "Georgia", false, FontWeight.Normal); - ft.registerFont("/Library/Fonts/Georgia Bold.ttf", FontFamily.SansSerif, "Georgia", false, FontWeight.Bold); - ft.registerFont("/Library/Fonts/Georgia Italic.ttf", FontFamily.SansSerif, "Georgia", true, FontWeight.Normal); - ft.registerFont("/Library/Fonts/Georgia Bold Italic.ttf", FontFamily.SansSerif, "Georgia", true, FontWeight.Bold); - ft.registerFont("/Library/Fonts/Georgia.ttf", FontFamily.SansSerif, "Georgia", false, FontWeight.Normal); - ft.registerFont("/Library/Fonts/Georgia Bold.ttf", FontFamily.SansSerif, "Georgia", false, FontWeight.Bold); - ft.registerFont("/Library/Fonts/Georgia Italic.ttf", FontFamily.SansSerif, "Georgia", true, FontWeight.Normal); - ft.registerFont("/Library/Fonts/Georgia Bold Italic.ttf", FontFamily.SansSerif, "Georgia", true, FontWeight.Bold); + ft.registerFont("/Library/Fonts/Georgia.ttf", FontFamily.Serif, "Georgia", false, FontWeight.Normal); + ft.registerFont("/Library/Fonts/Georgia Bold.ttf", FontFamily.Serif, "Georgia", false, FontWeight.Bold); + ft.registerFont("/Library/Fonts/Georgia Italic.ttf", FontFamily.Serif, "Georgia", true, FontWeight.Normal); + ft.registerFont("/Library/Fonts/Georgia Bold Italic.ttf", FontFamily.Serif, "Georgia", true, FontWeight.Bold); } } diff --git a/src/dlangui/widgets/styles.d b/src/dlangui/widgets/styles.d index 74495bc4..96821a98 100644 --- a/src/dlangui/widgets/styles.d +++ b/src/dlangui/widgets/styles.d @@ -827,8 +827,8 @@ class Theme : Style { _fontSize = 9 | SIZE_IN_POINTS_FLAG; // TODO: from settings or screen properties / DPI _fontStyle = FONT_STYLE_NORMAL; _fontWeight = 400; - //_fontFace = "Arial"; // TODO: from settings - _fontFace = "Verdana"; // TODO: from settings + _fontFace = "Arial"; // TODO: from settings + //_fontFace = "Verdana"; // TODO: from settings _fontFamily = FontFamily.SansSerif; _minHeight = 0; _minWidth = 0;