]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/pangox11.cpp
merged 2.4 branch into the trunk
[wxWidgets.git] / src / x11 / pangox11.cpp
diff --git a/src/x11/pangox11.cpp b/src/x11/pangox11.cpp
new file mode 100644 (file)
index 0000000..17108cf
--- /dev/null
@@ -0,0 +1,276 @@
+/**
+ * This file gets included from dcclient.cpp and implements 
+ * the X11 interface to Pango. 
+ * Copyright (C) Owen Taylor and Robert Roebling.
+ */
+
+/* Declaration */
+
+void
+x11_draw_glyphs( Drawable       drawable,
+                        GC             gc,
+                        PangoFont     *font,
+                        int            x,
+                        int            y,
+                        PangoGlyphString *glyphs);
+                 
+void 
+x11_draw_layout_line_with_colors( Drawable         drawable,
+                                  GC               gc,
+                                  int              x, 
+                                  int              y,
+                                  PangoLayoutLine  *line,
+                                  XColor           *foreground,
+                                  XColor           *background);
+                                  
+void 
+x11_draw_layout_with_colors( Drawable      drawable,
+                             GC            gc,
+                             int           x, 
+                             int           y,
+                             PangoLayout  *layout,
+                             XColor       *foreground,
+                             XColor       *background);
+                             
+void 
+x11_draw_layout( Drawable     drawable,
+                 GC           gc,
+                 int          x, 
+                 int          y,
+                 PangoLayout *layout);
+                 
+void
+x11_pango_get_item_properties( PangoItem      *item,
+                               PangoUnderline *uline,
+                               gboolean       *strikethrough,
+                               gint           *rise,
+                               PangoColor     *fg_color,
+                               gboolean       *fg_set,
+                               PangoColor     *bg_color,
+                               gboolean       *bg_set,
+                               gboolean       *shape_set,
+                               PangoRectangle *ink_rect,
+                               PangoRectangle *logical_rect);
+
+/* Implementation */
+
+void
+x11_draw_glyphs( Drawable       drawable,
+                        GC             gc,
+                        PangoFont     *font,
+                        int            x,
+                        int            y,
+                        PangoGlyphString *glyphs)
+{
+    if (PANGO_XFT_IS_FONT (font))
+    {
+        pango_xft_picture_render( wxGlobalDisplay(), drawable, drawable, font, glyphs, x, y );
+    }
+    else
+    {
+        pango_x_render( wxGlobalDisplay(), drawable, gc, font, glyphs, x, y );
+    }
+}
+
+void 
+x11_draw_layout_line_with_colors( Drawable         drawable,
+                                  GC               gc,
+                                  int              x, 
+                                  int              y,
+                                  PangoLayoutLine  *line,
+                                  XColor           *foreground,
+                                  XColor           *background)
+{
+    PangoRectangle overall_rect;
+    PangoRectangle logical_rect;
+    PangoRectangle ink_rect;
+    PangoContext *context;
+    gint x_off = 0;
+    gint rise = 0;
+
+    context = pango_layout_get_context (line->layout);
+  
+    pango_layout_line_get_extents (line,NULL, &overall_rect);
+  
+    GSList *tmp_list = line->runs;
+    while (tmp_list)
+    {
+        PangoUnderline uline = PANGO_UNDERLINE_NONE;
+        PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data;
+        PangoColor fg_color, bg_color;
+        gboolean strike, fg_set, bg_set, shape_set;
+        gint risen_y;
+      
+        tmp_list = tmp_list->next;
+      
+        x11_pango_get_item_properties (run->item, &uline, 
+            &strike, &rise,  &fg_color, &fg_set, &bg_color, &bg_set, 
+            &shape_set, &ink_rect, &logical_rect);
+
+        /* we subtract the rise because X coordinates are upside down */
+        risen_y = y - rise / PANGO_SCALE;
+      
+        if (!shape_set)
+        {
+            if (uline == PANGO_UNDERLINE_NONE)
+                pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect);
+            else
+                pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect);
+        }
+
+#if 0
+           XDrawRectangle( drawable, gc, TRUE,
+                             x + (x_off + logical_rect.x) / PANGO_SCALE,
+                             risen_y + overall_rect.y / PANGO_SCALE,
+                             logical_rect.width / PANGO_SCALE,
+                             overall_rect.height / PANGO_SCALE);
+#endif
+
+        if (!shape_set)
+        {
+            int gx = x + x_off / PANGO_SCALE;
+            int gy = risen_y;
+          
+            x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs);
+        }
+      
+        if (uline ==  PANGO_UNDERLINE_SINGLE)
+        {  
+            XDrawLine( wxGlobalDisplay(), drawable, gc,
+                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
+                          risen_y + 1,
+                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
+                         risen_y + 1);
+        }
+
+        x_off += logical_rect.width;
+    }
+}
+
+void 
+x11_draw_layout_with_colors( Drawable      drawable,
+                             GC            gc,
+                             int           x, 
+                             int           y,
+                             PangoLayout  *layout,
+                             XColor       *foreground,
+                             XColor       *background)
+{
+    PangoLayoutIter *iter = pango_layout_get_iter (layout);
+  
+    do
+    {
+        PangoLayoutLine *line = pango_layout_iter_get_line (iter);
+      
+        PangoRectangle logical_rect;
+        pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
+        
+        int baseline = pango_layout_iter_get_baseline (iter);
+      
+        x11_draw_layout_line_with_colors( drawable, gc,
+                                          x + logical_rect.x / PANGO_SCALE,
+                                          y + baseline / PANGO_SCALE,
+                                          line,
+                                          foreground,
+                                          background);
+                                          
+    } while (pango_layout_iter_next_line (iter));
+
+    pango_layout_iter_free (iter);
+}
+
+void 
+x11_draw_layout( Drawable     drawable,
+                 GC           gc,
+                 int          x, 
+                 int          y,
+                 PangoLayout *layout)
+{
+    wxCHECK_RET( layout, wxT("No layout") );
+
+    x11_draw_layout_with_colors (drawable, gc, x, y, layout, NULL, NULL);
+}
+
+void
+x11_pango_get_item_properties( PangoItem      *item,
+                               PangoUnderline *uline,
+                               gboolean       *strikethrough,
+                               gint           *rise,
+                               PangoColor     *fg_color,
+                               gboolean       *fg_set,
+                               PangoColor     *bg_color,
+                               gboolean       *bg_set,
+                               gboolean       *shape_set,
+                               PangoRectangle *ink_rect,
+                               PangoRectangle *logical_rect)
+{
+  GSList *tmp_list = item->analysis.extra_attrs;
+
+  if (strikethrough)
+      *strikethrough = FALSE;
+  
+  if (fg_set)
+    *fg_set = FALSE;
+  
+  if (bg_set)
+    *bg_set = FALSE;
+
+  if (shape_set)
+    *shape_set = FALSE;
+
+  if (rise)
+    *rise = 0;
+
+  while (tmp_list)
+    {
+      PangoAttribute *attr = (PangoAttribute *) tmp_list->data;
+
+      switch (attr->klass->type)
+       {
+       case PANGO_ATTR_UNDERLINE:
+         if (uline)
+           *uline = (PangoUnderline) ((PangoAttrInt *)attr)->value;
+         break;
+
+       case PANGO_ATTR_STRIKETHROUGH:
+           if (strikethrough)
+               *strikethrough = ((PangoAttrInt *)attr)->value;
+           break;
+           
+       case PANGO_ATTR_FOREGROUND:
+         if (fg_color)
+           *fg_color = ((PangoAttrColor *)attr)->color;
+         if (fg_set)
+           *fg_set = TRUE;
+         
+         break;
+         
+       case PANGO_ATTR_BACKGROUND:
+         if (bg_color)
+           *bg_color = ((PangoAttrColor *)attr)->color;
+         if (bg_set)
+           *bg_set = TRUE;
+         
+         break;
+
+       case PANGO_ATTR_SHAPE:
+         if (shape_set)
+           *shape_set = TRUE;
+         if (logical_rect)
+           *logical_rect = ((PangoAttrShape *)attr)->logical_rect;
+         if (ink_rect)
+           *ink_rect = ((PangoAttrShape *)attr)->ink_rect;
+         break;
+
+        case PANGO_ATTR_RISE:
+          if (rise)
+            *rise = ((PangoAttrInt *)attr)->value;
+          break;
+          
+       default:
+         break;
+       }
+      tmp_list = tmp_list->next;
+    }
+}
+