mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
gg: native rendering mode on macOS
This commit is contained in:
24
vlib/gg/gg.v
24
vlib/gg/gg.v
@@ -40,6 +40,7 @@ pub:
|
||||
bg_color gx.Color
|
||||
init_fn FNCb = voidptr(0)
|
||||
frame_fn FNCb = voidptr(0)
|
||||
native_frame_fn FNCb = voidptr(0)
|
||||
cleanup_fn FNCb = voidptr(0)
|
||||
fail_fn FNFail = voidptr(0)
|
||||
event_fn FNEvent = voidptr(0)
|
||||
@@ -65,6 +66,7 @@ pub:
|
||||
font_bytes_bold []byte
|
||||
font_bytes_mono []byte
|
||||
font_bytes_italic []byte
|
||||
native_rendering bool // Cocoa on macOS/iOS, GDI+ on Windows
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
@@ -75,6 +77,8 @@ mut:
|
||||
image_cache []Image
|
||||
needs_refresh bool = true
|
||||
ticks int
|
||||
pub:
|
||||
native_rendering bool
|
||||
pub mut:
|
||||
scale f32 = 1.0
|
||||
// will get set to 2.0 for retina, will remain 1.0 for normal
|
||||
@@ -169,6 +173,9 @@ fn gg_init_sokol_window(user_data voidptr) {
|
||||
g.config.init_fn(g.config.user_data)
|
||||
}
|
||||
// Create images now that we can do that after sg is inited
|
||||
if g.native_rendering {
|
||||
return
|
||||
}
|
||||
for i in 0 .. g.image_cache.len {
|
||||
g.image_cache[i].init_sokol_image()
|
||||
}
|
||||
@@ -179,6 +186,9 @@ fn gg_frame_fn(user_data voidptr) {
|
||||
if ctx.config.frame_fn == voidptr(0) {
|
||||
return
|
||||
}
|
||||
if ctx.native_rendering {
|
||||
// return
|
||||
}
|
||||
if ctx.ui_mode && !ctx.needs_refresh {
|
||||
// Draw 3 more frames after the "stop refresh" command
|
||||
ctx.ticks++
|
||||
@@ -256,6 +266,7 @@ pub fn new_context(cfg Config) &Context {
|
||||
render_text: cfg.font_path != '' || cfg.font_bytes_normal.len > 0
|
||||
ft: 0
|
||||
ui_mode: cfg.ui_mode
|
||||
native_rendering: cfg.native_rendering
|
||||
}
|
||||
g.set_bg_color(cfg.bg_color)
|
||||
// C.printf('new_context() %p\n', cfg.user_data)
|
||||
@@ -273,6 +284,7 @@ pub fn new_context(cfg Config) &Context {
|
||||
sample_count: cfg.sample_count
|
||||
high_dpi: true
|
||||
fullscreen: cfg.fullscreen
|
||||
native_render: cfg.native_rendering
|
||||
}
|
||||
if cfg.use_ortho {
|
||||
} else {
|
||||
@@ -292,6 +304,12 @@ pub fn (mut ctx Context) set_bg_color(c gx.Color) {
|
||||
|
||||
// TODO: Fix alpha
|
||||
pub fn (ctx &Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
C.darwin_draw_rect(x, ctx.height - (y + h), w, h, c)
|
||||
return
|
||||
}
|
||||
}
|
||||
if c.a != 255 {
|
||||
sgl.load_pipeline(ctx.timage_pip)
|
||||
}
|
||||
@@ -357,6 +375,12 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.C
|
||||
}
|
||||
|
||||
pub fn (ctx &Context) draw_circle(x f32, y f32, r f32, c gx.Color) {
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
C.darwin_draw_circle(x - r + 1, ctx.height - (y + r + 3), r, c)
|
||||
return
|
||||
}
|
||||
}
|
||||
if ctx.scale == 1 {
|
||||
ctx.draw_circle_with_segments(x, y, r, 10, c)
|
||||
} else {
|
||||
|
||||
@@ -2,3 +2,19 @@ module gg
|
||||
|
||||
#include "@VROOT/vlib/gg/gg_darwin.m"
|
||||
fn C.gg_get_screen_size() Size
|
||||
|
||||
fn C.darwin_draw_string(x int, y int, s string)
|
||||
|
||||
fn C.darwin_text_width(s string) int
|
||||
|
||||
fn C.darwin_window_refresh()
|
||||
|
||||
fn C.darwin_draw_rect(f32, f32, f32, f32)
|
||||
|
||||
fn C.darwin_create_image() Image
|
||||
|
||||
fn C.darwin_draw_image(f32, f32, f32, f32, &Image)
|
||||
|
||||
fn C.darwin_draw_circle(f32, f32, f32)
|
||||
|
||||
//, gx.Color c)
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
NSColor* nscolor(gx__Color c) {
|
||||
float red= (float)c.r / 255.0f;
|
||||
float green= (float)c.g / 255.0f;
|
||||
float blue= (float)c.b / 255.0f;
|
||||
return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:1.0f];
|
||||
}
|
||||
|
||||
NSString* nsstring(string s) {
|
||||
return [ [ NSString alloc ] initWithBytesNoCopy:s.str length:s.len
|
||||
encoding:NSUTF8StringEncoding freeWhenDone: false];
|
||||
}
|
||||
|
||||
|
||||
gg__Size gg_get_screen_size() {
|
||||
NSScreen *screen = [NSScreen mainScreen];
|
||||
NSDictionary *description = [screen deviceDescription];
|
||||
@@ -12,3 +25,101 @@ gg__Size gg_get_screen_size() {
|
||||
return res;
|
||||
}
|
||||
|
||||
void darwin_draw_string(int x, int y, string s, gx__TextCfg cfg) {
|
||||
NSFont* font = [NSFont userFontOfSize: 0]; //cfg.size];
|
||||
// # NSFont* font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
|
||||
if (cfg.mono) {
|
||||
// # font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
|
||||
font = [NSFont fontWithName:@"Menlo" size:cfg.size-5];
|
||||
}
|
||||
if (cfg.bold) {
|
||||
font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
|
||||
}
|
||||
|
||||
|
||||
NSDictionary* attr = @{
|
||||
NSForegroundColorAttributeName: nscolor(cfg.color),
|
||||
//NSParagraphStyleAttributeName: paragraphStyle,
|
||||
NSFontAttributeName: font,
|
||||
};
|
||||
[nsstring(s) drawAtPoint:NSMakePoint(x,y-15) withAttributes:attr];
|
||||
}
|
||||
|
||||
int darwin_text_width(string s) {
|
||||
// println('text_width "$s" len=$s.len')
|
||||
NSString* n = @"";
|
||||
if (s.len == 1) {
|
||||
// println('len=1')
|
||||
n=[NSString stringWithFormat:@"%c" , s.str[0]];
|
||||
}
|
||||
else {
|
||||
n = nsstring(s);
|
||||
}
|
||||
/*
|
||||
# if (!defaultFont){
|
||||
# defaultFont = [NSFont userFontOfSize: ui__DEFAULT_FONT_SIZE];
|
||||
# }
|
||||
# NSDictionary *attrs = @{
|
||||
# NSFontAttributeName: defaultFont,
|
||||
# };
|
||||
*/
|
||||
NSSize size = [n sizeWithAttributes:nil];
|
||||
// # printf("!!!%f\n", ceil(size.width));
|
||||
return (int)(ceil(size.width));
|
||||
}
|
||||
|
||||
|
||||
void darwin_draw_rect(float x, float y, float width, float height, gx__Color c) {
|
||||
NSColor* color = nscolor(c);
|
||||
NSRect rect = NSMakeRect(x, y, width, height);
|
||||
[color setFill];
|
||||
NSRectFill(rect);
|
||||
}
|
||||
|
||||
|
||||
void darwin_window_refresh() {
|
||||
//[g_view setNeedsDisplay:YES];
|
||||
// update UI on the main thread TODO separate fn
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[g_view setNeedsDisplay:YES];
|
||||
});
|
||||
|
||||
//puts("refresh");
|
||||
//[g_view drawRect:NSMakeRect(0,0,2000,2000)];
|
||||
//[[NSGraphicsContext currentContext] flushGraphics];
|
||||
}
|
||||
|
||||
gg__Image darwin_create_image(string path_) {
|
||||
// file = file.trim_space()
|
||||
NSString* path = nsstring(path_);
|
||||
NSImage* img = [[NSImage alloc] initWithContentsOfFile:path];
|
||||
if (img == 0) {
|
||||
}
|
||||
NSSize size = [img size];
|
||||
gg__Image res;
|
||||
res.width = size.width;
|
||||
res.height = size.height;
|
||||
res.path = path_;
|
||||
res.ok = true;
|
||||
//printf("inited img width=%d\n", res.width) ;
|
||||
// need __brige_retained so that the pointer is not freed by ARC
|
||||
res.data = (__bridge_retained voidptr)(img);
|
||||
return res;
|
||||
}
|
||||
|
||||
void darwin_draw_image(float x, float y, float w, float h, gg__Image* img) {
|
||||
NSImage* i= (__bridge NSImage*)(img->data);
|
||||
[i drawInRect:NSMakeRect(x,y,w,h)];
|
||||
}
|
||||
|
||||
void darwin_draw_circle(float x, float y, float d, gx__Color color) {
|
||||
NSColor* c = nscolor(color);
|
||||
NSRect rect = NSMakeRect(x, y, d * 2, d * 2);
|
||||
NSBezierPath* circlePath = [NSBezierPath bezierPath];
|
||||
[circlePath appendBezierPathWithOvalInRect: rect];
|
||||
[c setFill];
|
||||
// [circlePath stroke];
|
||||
[circlePath fill];
|
||||
// NSRectFill(rect);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,21 @@ fn C.sg_isvalid() bool
|
||||
|
||||
// TODO return ?Image
|
||||
pub fn (mut ctx Context) create_image(file string) Image {
|
||||
// println('\ncreate_image("$file")')
|
||||
if !os.exists(file) {
|
||||
return Image{}
|
||||
}
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
// return C.darwin_create_image(file)
|
||||
mut img := C.darwin_create_image(file)
|
||||
// println('created macos image: $img.path w=$img.width')
|
||||
// C.printf('p = %p\n', img.data)
|
||||
img.id = ctx.image_cache.len
|
||||
ctx.image_cache << img
|
||||
return img
|
||||
}
|
||||
}
|
||||
if !C.sg_isvalid() {
|
||||
// Sokol is not initialized yet, add stbi object to a queue/cache
|
||||
// ctx.image_queue << file
|
||||
@@ -142,6 +157,18 @@ pub fn (ctx &Context) draw_image(x f32, y f32, width f32, height f32, img_ &Imag
|
||||
return
|
||||
}
|
||||
img := ctx.image_cache[img_.id] // fetch the image from cache
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
if img_.width == 0 {
|
||||
return
|
||||
}
|
||||
if !os.exists(img_.path) {
|
||||
return
|
||||
}
|
||||
C.darwin_draw_image(x, ctx.height - (y + height), width, height, img_)
|
||||
return
|
||||
}
|
||||
}
|
||||
if !img.simg_ok {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -35,6 +35,13 @@ struct FTConfig {
|
||||
bytes_italic []byte
|
||||
}
|
||||
|
||||
struct StringToRender {
|
||||
x int
|
||||
y int
|
||||
text string
|
||||
cfg gx.TextCfg
|
||||
}
|
||||
|
||||
fn new_ft(c FTConfig) ?&FT {
|
||||
if c.font_path == '' {
|
||||
if c.bytes_normal.len > 0 {
|
||||
@@ -150,6 +157,17 @@ fn (ctx &Context) set_cfg(cfg gx.TextCfg) {
|
||||
}
|
||||
|
||||
pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) {
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
if cfg.align == gx.align_right {
|
||||
width := ctx.text_width(text_)
|
||||
C.darwin_draw_string(x - width, ctx.height - y, text_, cfg)
|
||||
} else {
|
||||
C.darwin_draw_string(x, ctx.height - y, text_, cfg)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if !ctx.font_inited {
|
||||
eprintln('gg: draw_text(): font not initialized')
|
||||
return
|
||||
@@ -177,6 +195,11 @@ pub fn (ft &FT) flush() {
|
||||
}
|
||||
|
||||
pub fn (ctx &Context) text_width(s string) int {
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
return C.darwin_text_width(s)
|
||||
}
|
||||
}
|
||||
// ctx.set_cfg(cfg) TODO
|
||||
if !ctx.font_inited {
|
||||
return 0
|
||||
@@ -187,6 +210,13 @@ pub fn (ctx &Context) text_width(s string) int {
|
||||
return int((buf[2] - buf[0]) / ctx.scale) +
|
||||
ctx.text_width('i') // TODO fix this in fontstash?
|
||||
}
|
||||
res := int((buf[2] - buf[0]) / ctx.scale)
|
||||
// println('TW "$s" = $res')
|
||||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
return res * 2
|
||||
}
|
||||
}
|
||||
return int((buf[2] - buf[0]) / ctx.scale)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user