diff --git a/basis/cairo/authors.txt b/basis/cairo/authors.txt index 68d35d192b..4023d08987 100644 --- a/basis/cairo/authors.txt +++ b/basis/cairo/authors.txt @@ -1,2 +1,3 @@ Sampo Vuori Doug Coleman +Slava Pestov diff --git a/basis/cairo/cairo.factor b/basis/cairo/cairo.factor index 65ee7e28fd..9f12d9c5f8 100755 --- a/basis/cairo/cairo.factor +++ b/basis/cairo/cairo.factor @@ -1,7 +1,9 @@ ! Copyright (C) 2008 Doug Coleman. +! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: cairo.ffi alien.c-types kernel accessors sequences -namespaces fry continuations destructors math images.memory ; +USING: colors fonts cairo.ffi alien alien.c-types kernel accessors +sequences namespaces fry continuations destructors math images +images.memory ; IN: cairo ERROR: cairo-error message ; @@ -43,4 +45,18 @@ ERROR: cairo-error message ; &cairo_surface_destroy cairo_create &cairo_destroy @ - ] make-memory-bitmap ; inline + ] make-memory-bitmap + BGRA >>component-order ; inline + +: dummy-cairo ( -- cr ) + #! Sometimes we want a dummy context; eg with Pango, we want + #! to measure text dimensions to create a new image context with, + #! but we need an existing context to measure text dimensions + #! with so we use the dummy. + \ dummy-cairo [ + CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create + cairo_create + ] initialize-alien ; + +: set-source-color ( cr color -- ) + >rgba-components cairo_set_source_rgba ; \ No newline at end of file diff --git a/basis/core-graphics/core-graphics.factor b/basis/core-graphics/core-graphics.factor index 4a53f5a05c..5e95e2e36e 100644 --- a/basis/core-graphics/core-graphics.factor +++ b/basis/core-graphics/core-graphics.factor @@ -126,4 +126,5 @@ PRIVATE> ] initialize-alien ; : make-bitmap-image ( dim quot -- image ) - '[ &CGContextRelease @ ] make-memory-bitmap ; inline + '[ &CGContextRelease @ ] make-memory-bitmap + ARGB >>component-order ; inline diff --git a/basis/glib/glib.factor b/basis/glib/glib.factor index 4c3f6ecb4e..cfb58939ff 100644 --- a/basis/glib/glib.factor +++ b/basis/glib/glib.factor @@ -24,6 +24,7 @@ LIBRARY: glib TYPEDEF: void* gpointer TYPEDEF: int gint +TYPEDEF: bool gboolean FUNCTION: void g_free ( gpointer mem ) ; diff --git a/basis/images/images.factor b/basis/images/images.factor index 88051ac57d..210afef640 100644 --- a/basis/images/images.factor +++ b/basis/images/images.factor @@ -34,7 +34,7 @@ TUPLE: image dim component-order bitmap ; GENERIC: load-image* ( path tuple -- image ) : add-dummy-alpha ( seq -- seq' ) - 3 [ 255 suffix ] map concat ; + 3 [ 255 suffix ] map concat ; : normalize-floats ( byte-array -- byte-array ) byte-array>float-array [ 255.0 * >integer ] B{ } map-as ; @@ -63,8 +63,7 @@ M: R16G16B16 normalize-component-order* drop RGB16>8 add-dummy-alpha ; : BGR>RGB ( bitmap bytes-per-pixel -- pixels ) - dup - [ 3 head-slice reverse-here ] each ; inline + [ 3 cut [ reverse ] dip append ] map B{ } join ; inline M: BGRA normalize-component-order* drop 4 BGR>RGB ; @@ -75,6 +74,15 @@ M: RGB normalize-component-order* M: BGR normalize-component-order* drop 3 BGR>RGB add-dummy-alpha ; +: ARGB>RGBA ( bitmap -- bitmap' ) + 4 [ unclip suffix ] map B{ } join ; + +M: ARGB normalize-component-order* + drop ARGB>RGBA ; + +M: ABGR normalize-component-order* + drop ARGB>RGBA 4 BGR>RGB ; + GENERIC: normalize-scan-line-order ( image -- image ) M: image normalize-scan-line-order ; diff --git a/basis/images/memory/memory.factor b/basis/images/memory/memory.factor index 6790239015..1a977b604e 100644 --- a/basis/images/memory/memory.factor +++ b/basis/images/memory/memory.factor @@ -20,8 +20,7 @@ IN: images.memory [ bitmap-data ] keep swap >>dim - swap >>bitmap - little-endian? ARGB BGRA ? >>component-order ; + swap >>bitmap ; PRIVATE> diff --git a/basis/opengl/textures/textures.factor b/basis/opengl/textures/textures.factor index f65a7ac222..79af9be48b 100644 --- a/basis/opengl/textures/textures.factor +++ b/basis/opengl/textures/textures.factor @@ -17,7 +17,7 @@ GENERIC: component-order>format ( component-order -- format type ) M: RGBA component-order>format drop GL_RGBA GL_UNSIGNED_BYTE ; M: ARGB component-order>format drop GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8_REV ; -M: BGRA component-order>format drop GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8 ; +M: BGRA component-order>format drop GL_BGRA_EXT GL_UNSIGNED_BYTE ; : repeat-last ( seq n -- seq' ) over peek pad-tail concat ; diff --git a/basis/pango/cairo/authors.txt b/basis/pango/cairo/authors.txt new file mode 100644 index 0000000000..367ba74d80 --- /dev/null +++ b/basis/pango/cairo/authors.txt @@ -0,0 +1,2 @@ +Matthew Willis +Slava Pestov diff --git a/basis/pango/cairo/cairo.factor b/basis/pango/cairo/cairo.factor index 98988cb4eb..e30c800294 100644 --- a/basis/pango/cairo/cairo.factor +++ b/basis/pango/cairo/cairo.factor @@ -1,4 +1,5 @@ ! Copyright (C) 2008 Matthew Willis. +! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. ! ! pangocairo bindings, from pango/pangocairo.h @@ -101,17 +102,12 @@ MEMO: (cache-font) ( font -- open-font ) : parse-font-metrics ( metrics -- metrics' ) [ metrics new ] dip - { - [ pango_font_metrics_get_ascent PANGO_SCALE /f >>height ] - [ pango_font_metrics_get_descent PANGO_SCALE /f >>descent ] - [ drop 0 >>leading ] - [ drop 0 >>cap-height ] - [ drop 0 >>x-height ] - } cleave + [ pango_font_metrics_get_ascent PANGO_SCALE /f >>height ] + [ pango_font_metrics_get_descent PANGO_SCALE /f >>descent ] bi dup [ height>> ] [ descent>> ] bi - >>ascent ; MEMO: (cache-font-metrics) ( font -- metrics ) [ get-font-metrics parse-font-metrics ] with-destructors ; : cache-font-metrics ( font -- metrics ) - strip-font-colors (cache-font-metrics) ; + strip-font-colors (cache-font-metrics) ; \ No newline at end of file diff --git a/basis/pango/layouts/layouts.factor b/basis/pango/layouts/layouts.factor index 207ea95ded..5fbad6d16e 100644 --- a/basis/pango/layouts/layouts.factor +++ b/basis/pango/layouts/layouts.factor @@ -1,8 +1,10 @@ ! Copyright (C) 2008 Matthew Willis. ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays alien alien.c-types alien.syntax math destructors accessors assocs -namespaces kernel pango pango.fonts pango.cairo cairo.ffi glib unicode.data ; +USING: arrays sequences alien alien.c-types alien.destructors +alien.syntax math math.vectors destructors combinators colors fonts +accessors assocs namespaces kernel pango pango.fonts pango.cairo cairo +cairo.ffi glib unicode.data locals images cache init ; IN: pango.layouts LIBRARY: pango @@ -32,16 +34,45 @@ FUNCTION: int pango_layout_get_baseline ( PangoLayout* layout ) ; FUNCTION: void -pango_layout_get_pixel_extents ( PangoLayout *layout, PangoRectangle *ink_rect, PangoRectangle *logical_rect ) ; +pango_layout_get_pixel_extents ( PangoLayout* layout, PangoRectangle* ink_rect, PangoRectangle* logical_rect ) ; + +FUNCTION: PangoLayoutLine* +pango_layout_get_line_readonly ( PangoLayout* layout, int line ) ; + +FUNCTION: void +pango_layout_line_index_to_x ( PangoLayoutLine* line, int index_, gboolean trailing, int* x_pos ) ; + +FUNCTION: gboolean +pango_layout_line_x_to_index ( PangoLayoutLine* line, int x_pos, int* index_, int* trailing ) ; + +FUNCTION: PangoLayoutIter* +pango_layout_get_iter ( PangoLayout* layout ) ; + +FUNCTION: int +pango_layout_iter_get_baseline ( PangoLayoutIter* iter ) ; + +FUNCTION: void +pango_layout_iter_free ( PangoLayoutIter* iter ) ; + +DESTRUCTOR: pango_layout_iter_free : layout-dim ( layout -- dim ) 0 0 [ pango_layout_get_pixel_size ] 2keep [ *int ] bi@ 2array ; -ERROR: bad-font name ; +: layout-extents ( layout -- ink-rect logical-rect ) + "PangoRectangle" + "PangoRectangle" + [ pango_layout_get_pixel_extents ] 2keep + [ PangoRectangle>rect ] bi@ ; + +: layout-baseline ( layout -- baseline ) + pango_layout_get_iter &pango_layout_iter_free + pango_layout_iter_get_baseline + PANGO_SCALE /f ; : set-layout-font ( str layout -- ) - swap cache-font-description pango_layout_set_font_description ; + swap pango_layout_set_font_description ; : set-layout-text ( str layout -- ) #! Replace nulls with something else since Pango uses null-terminated @@ -49,15 +80,71 @@ ERROR: bad-font name ; swap { { 0 CHAR: zero-width-no-break-space } } substitute -1 pango_layout_set_text ; -: ( text font cairo -- layout ) +: ( text font -- layout ) + dummy-cairo pango_cairo_create_layout |g_object_unref + [ set-layout-font ] keep + [ set-layout-text ] keep ; + +: set-foreground ( cr font -- ) + foreground>> set-source-color ; + +: fill-background ( cr font dim -- ) + [ background>> set-source-color ] + [ [ 0 0 ] dip first2 cairo_rectangle ] bi-curry* + [ cairo_fill ] + tri ; + +:: fill-selection-background ( cr loc dim layout string -- ) + ; + +: set-text-position ( cr loc -- ) + first2 cairo_move_to ; + +: layout-metrics ( dim baseline -- metrics ) + metrics new + swap >>ascent + swap first2 [ >>width ] [ >>height ] bi* + dup [ height>> ] [ ascent>> ] bi - >>descent ; + +TUPLE: layout font layout metrics image loc dim disposed ; + +:: ( font string -- line ) [ - pango_cairo_create_layout |g_object_unref - [ set-layout-font ] keep - [ set-layout-text ] keep + ! TODO: metrics and loc + [let* | open-font [ font cache-font-description ] + layout [ string open-font ] + logical-rect [ layout layout-extents ] ink-rect [ ] + baseline [ layout layout-baseline ] + logical-loc [ logical-rect loc>> ] + logical-dim [ logical-rect dim>> ] + ink-loc [ ink-rect loc>> ] + ink-dim [ ink-rect dim>> ] + metrics [ logical-dim baseline layout-metrics ] | + open-font layout metrics + ink-dim [ + { + [ layout pango_cairo_update_layout ] + [ font ink-dim fill-background ] + [ font set-foreground ] + [ ink-loc ink-dim layout string fill-selection-background ] + [ logical-loc ink-loc v- set-text-position ] + [ layout pango_cairo_show_layout ] + } cleave + ] make-bitmap-image + logical-loc ink-loc v- + logical-dim + ] + f layout boa ] with-destructors ; -: dummy-cairo ( -- cr ) - \ dummy-cairo [ - CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create - cairo_create - ] initialize-alien ; +M: layout dispose* layout>> g_object_unref ; + +SYMBOL: cached-layouts + +: cached-layout ( font string -- layout ) + cached-layouts get [ ] 2cache ; + +: cached-line ( font string -- line ) + cached-layout layout>> 0 pango_layout_get_line_readonly ; + +[ cached-layouts set-global ] "pango.layouts" add-init-hook \ No newline at end of file diff --git a/basis/pango/pango.factor b/basis/pango/pango.factor index ae78f530bb..74e171e5eb 100644 --- a/basis/pango/pango.factor +++ b/basis/pango/pango.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Matthew Willis. +! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license -USING: system alien.destructors alien.c-types alien.syntax alien -combinators ; +USING: arrays system alien.destructors alien.c-types alien.syntax alien +combinators math.rectangles kernel ; IN: pango ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -21,5 +22,16 @@ CONSTANT: PANGO_SCALE 1024 FUNCTION: PangoContext* pango_context_new ( ) ; +C-STRUCT: PangoRectangle + { "int" "x" } + { "int" "y" } + { "int" "width" } + { "int" "height" } ; + +: PangoRectangle>rect ( PangoRectangle -- rect ) + [ [ PangoRectangle-x ] [ PangoRectangle-y ] bi 2array ] + [ [ PangoRectangle-width ] [ PangoRectangle-height ] bi 2array ] bi + ; + : dummy-pango-context ( -- context ) \ dummy-pango-context [ pango_context_new ] initialize-alien ; \ No newline at end of file diff --git a/basis/ui/text/pango/authors.txt b/basis/ui/text/pango/authors.txt new file mode 100644 index 0000000000..d4f5d6b3ae --- /dev/null +++ b/basis/ui/text/pango/authors.txt @@ -0,0 +1 @@ +Slava Pestov \ No newline at end of file diff --git a/basis/ui/text/pango/pango.factor b/basis/ui/text/pango/pango.factor new file mode 100644 index 0000000000..02ed2c49a8 --- /dev/null +++ b/basis/ui/text/pango/pango.factor @@ -0,0 +1,44 @@ +! Copyright (C) 2009 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors alien.c-types assocs cache kernel math +namespaces opengl.textures pango.cairo pango.layouts +ui.gadgets.worlds ui.text ui.text.private ; +IN: ui.text.pango + +SINGLETON: pango-renderer + +M: pango-renderer init-text-rendering + >>text-handle drop ; + +M: pango-renderer string-dim cached-layout dim>> ; + +M: pango-renderer finish-text-rendering + text-handle>> purge-cache + cached-layouts get purge-cache ; + +: rendered-layout ( font string -- texture ) + world get text-handle>> + [ cached-layout [ image>> ] [ loc>> ] bi ] + 2cache ; + +M: pango-renderer draw-string ( font string -- ) + rendered-layout draw-texture ; + +M: pango-renderer x>offset ( x font string -- n ) + cached-line swap 0 0 + [ pango_layout_line_x_to_index drop ] 2keep + [ *int ] bi@ + ; + +M: pango-renderer offset>x ( n font string -- x ) + cached-line swap f + 0 [ pango_layout_line_index_to_x ] keep *int ; + +: missing-metrics ( metrics -- metrics ) 5 >>cap-height 5 >>x-height ; + +M: pango-renderer font-metrics ( font -- metrics ) + cache-font-metrics missing-metrics ; + +M: pango-renderer line-metrics ( font string -- metrics ) + cached-layout metrics>> missing-metrics ; + +pango-renderer font-renderer set-global \ No newline at end of file