void planner_print_job_text (PlannerPrintJob *job, gint x, gint y, const char *str) { g_return_if_fail (job != NULL); g_return_if_fail (str != NULL); PangoLayout *layout = gtk_print_context_create_pango_layout (job->pc); PlannerPrintJobPriv *priv; priv = job->priv; pango_layout_set_font_description (layout, priv->current_font); pango_layout_set_text (layout, str, -1); pango_layout_context_changed (layout); planner_print_job_moveto (job, x, y - priv->font_height); pango_cairo_show_layout (job->cr, layout); g_object_unref (layout); }
static void gwy_vector_layer_update_context(GwyVectorLayer *layer) { gwy_debug(" "); if (layer->layout) pango_layout_context_changed(layer->layout); }
void planner_print_job_show_clipped (PlannerPrintJob *job, gdouble x, gdouble y, const gchar *str, gdouble x1, gdouble y1, gdouble x2, gdouble y2) { PlannerPrintJobPriv *priv; gint height; priv = job->priv; x1 = MAX (x1, 0); x2 = MIN (x2, job->width); y1 = MAX (y1, 0); y2 = MIN (y2, job->height); /* Don't try to print anything if the text starts outside the clip rect. */ if (x < x1 || x > x2) { return; } cairo_save (job->cr); cairo_set_line_width (job->cr, 1); cairo_new_path (job->cr); planner_print_job_moveto (job, x1, y1); planner_print_job_lineto (job, x1, y2); planner_print_job_lineto (job, x2, y2); planner_print_job_lineto (job, x2, y1); cairo_close_path (job->cr); cairo_clip (job->cr); PangoLayout *layout = gtk_print_context_create_pango_layout (job->pc); pango_layout_set_text (layout, str, strlen(str)); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_width (layout, (x2 - x1) * PANGO_SCALE); pango_layout_set_font_description (layout, priv->current_font); pango_layout_context_changed (layout); pango_layout_get_pixel_size (layout, NULL, &height); planner_print_job_moveto (job, x, y - priv->font_height); pango_cairo_show_layout (job->cr, layout); g_object_unref (layout); cairo_restore (job->cr); }
void context_t::update(cairo_t* cr) { pango_cairo_update_context(cr, pango_context.get()); layouts.erase(std::remove_if(layouts.begin(), layouts.end(), [](const std::weak_ptr<layout_t>& layout) -> bool { return layout.expired(); }), layouts.end()); for(auto& layout_ref : layouts) { if(auto layout = layout_ref.lock()) pango_layout_context_changed(layout->layout.get()); } }
static void checkbutton_toggled (GtkWidget *widget, gpointer data) { GList *para_list; pango_context_set_base_dir (context, GTK_TOGGLE_BUTTON (widget)->active ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); para_list = paragraphs; while (para_list) { Paragraph *para = para_list->data; pango_layout_context_changed (para->layout); para_list = para_list->next; } gtk_widget_queue_resize (layout); }
static void reload_font () { GList *para_list; pango_context_set_font_description (context, font_description); para_list = paragraphs; while (para_list) { Paragraph *para = para_list->data; pango_layout_context_changed (para->layout); para_list = para_list->next; } if (layout) gtk_widget_queue_resize (layout); }
gdouble planner_print_job_get_extents (PlannerPrintJob *job, char *text) { PangoLayout *layout = gtk_print_context_create_pango_layout (job->pc); PlannerPrintJobPriv *priv; PangoRectangle ink; priv = job->priv; pango_layout_set_font_description (layout, priv->current_font); pango_layout_set_text (layout, text, -1); pango_cairo_update_layout (gtk_print_context_get_cairo_context(job->pc), layout); pango_layout_context_changed (layout); pango_layout_get_extents (layout, &ink, NULL); g_object_unref (layout); return ((gdouble)ink.width / PANGO_SCALE); }
static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len) { PangoFontMetrics* metrics; int w, h, desc, dir = -1; int ox = x, oy = y; pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), -1); pango_layout_get_pixel_size(ctxcanvas->fontlayout, &w, &h); metrics = pango_context_get_metrics(ctxcanvas->fontcontext, ctxcanvas->fontdesc, pango_context_get_language(ctxcanvas->fontcontext)); desc = (((pango_font_metrics_get_descent(metrics)) + PANGO_SCALE/2) / PANGO_SCALE); switch (ctxcanvas->canvas->text_alignment) { case CD_BASE_RIGHT: case CD_NORTH_EAST: case CD_EAST: case CD_SOUTH_EAST: x = x - w; break; case CD_BASE_CENTER: case CD_CENTER: case CD_NORTH: case CD_SOUTH: x = x - w/2; break; case CD_BASE_LEFT: case CD_NORTH_WEST: case CD_WEST: case CD_SOUTH_WEST: x = x; break; } if (ctxcanvas->canvas->invert_yaxis) dir = 1; switch (ctxcanvas->canvas->text_alignment) { case CD_BASE_LEFT: case CD_BASE_CENTER: case CD_BASE_RIGHT: y = y - (dir*h - desc); break; case CD_SOUTH_EAST: case CD_SOUTH_WEST: case CD_SOUTH: y = y - (dir*h); break; case CD_NORTH_EAST: case CD_NORTH: case CD_NORTH_WEST: y = y; break; case CD_CENTER: case CD_EAST: case CD_WEST: y = y - (dir*(h/2)); break; } if(!ctxcanvas->canvas->use_matrix) { ctxcanvas->fontmatrix.xx = 1; ctxcanvas->fontmatrix.xy = 0; ctxcanvas->fontmatrix.yx = 0; ctxcanvas->fontmatrix.yy = 1; ctxcanvas->fontmatrix.x0 = 0; ctxcanvas->fontmatrix.y0 = 0; } if (ctxcanvas->canvas->use_matrix || ctxcanvas->canvas->text_orientation) { PangoRectangle rect; double angle = ctxcanvas->canvas->text_orientation; if (ctxcanvas->canvas->text_orientation) pango_matrix_rotate(&ctxcanvas->fontmatrix, angle); pango_context_set_matrix (ctxcanvas->fontcontext, &ctxcanvas->fontmatrix); pango_layout_context_changed (ctxcanvas->fontlayout); pango_layout_get_pixel_extents(ctxcanvas->fontlayout, NULL, &rect); #if PANGO_VERSION_CHECK(1,16,0) pango_matrix_transform_pixel_rectangle(&ctxcanvas->fontmatrix, &rect); #endif if (ctxcanvas->canvas->text_orientation) { double cos_angle = cos(angle*CD_DEG2RAD); double sin_angle = sin(angle*CD_DEG2RAD); cdRotatePoint(ctxcanvas->canvas, x, y, ox, oy, &x, &y, sin_angle, cos_angle); } if (ctxcanvas->canvas->use_matrix) cdMatrixTransformPoint(ctxcanvas->xmatrix, x, y, &x, &y); /* Defines the new position (X,Y), considering the Pango rectangle transformed */ x += (int)rect.x; y += (int)rect.y; } cdgdkCheckSolidStyle(ctxcanvas, 1); if (ctxcanvas->canvas->new_region) { GdkRegion *rgn; gint *idx; gint range; pango_layout_line_get_x_ranges(pango_layout_get_line(ctxcanvas->fontlayout, 0), 0, len, &idx, &range); /* TODO: this is only the bounding box of the layout, not the text itself, must transform the text into a polygon. */ rgn = gdk_pango_layout_get_clip_region(ctxcanvas->fontlayout, x, y, idx, range); sCombineRegion(ctxcanvas, rgn); } else gdk_draw_layout(ctxcanvas->wnd, ctxcanvas->gc, x, y, ctxcanvas->fontlayout); pango_context_set_matrix(ctxcanvas->fontcontext, NULL); cdgdkCheckSolidStyle(ctxcanvas, 0); pango_font_metrics_unref(metrics); }
PangoLayout* gdip_pango_setup_layout (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc, RectF *box, GDIPCONST GpStringFormat *format, int **charsRemoved) { GpStringFormat *fmt; PangoLayout *layout; PangoContext *context; PangoRectangle logical; /* logical size of text (used for alignment) */ PangoRectangle ink; /* ink size of text (to pixel boundaries) */ PangoAttrList *list = NULL; GString *ftext; PangoTabArray *tabs; PangoLayoutIter *iter; int i; int FrameWidth; /* rc->Width (or rc->Height if vertical) */ int FrameHeight; /* rc->Height (or rc->Width if vertical) */ int FrameX; /* rc->X (or rc->Y if vertical) */ int FrameY; /* rc->Y (or rc->X if vertical) */ int y0; /* y0,y1,clipNN used for checking line positions vs. clip rectangle */ int y1; double clipx1; double clipx2; double clipy1; double clipy2; int trimSpace; /* whether or not to trim the space */ gchar *text = ucs2_to_utf8 (stringUnicode, length); if (!text) return NULL; length = strlen(text); if (charsRemoved) { (*charsRemoved) = GdipAlloc (sizeof (int) * length); if (!*charsRemoved) { GdipFree (text); return NULL; } memset (*charsRemoved, 0, sizeof (int) * length); } /* TODO - Digit substitution */ // g_warning ("layout >%s< (%d) [x %g, y %g, w %g, h %g] [font %s, %g points]", text, length, rc->X, rc->Y, rc->Width, FrameHeight, font->face, font->emSize); /* a NULL format is valid, it means get the generic default values (and free them later) */ if (!format) { GpStatus status = GdipStringFormatGetGenericDefault ((GpStringFormat **)&fmt); if (status != Ok) { GdipFree (text); return NULL; } } else { fmt = (GpStringFormat *)format; } layout = pango_cairo_create_layout (graphics->ct); /* context is owned by Pango (i.e. not referenced counted) do not free */ context = pango_layout_get_context (layout); pango_layout_set_font_description (layout, gdip_get_pango_font_description ((GpFont*) font)); if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height)); FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width)); FrameX = SAFE_FLOAT_TO_UINT32 (rc->Y); FrameY = SAFE_FLOAT_TO_UINT32 (rc->X); } else { FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width)); FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height)); FrameX = SAFE_FLOAT_TO_UINT32 (rc->X); FrameY = SAFE_FLOAT_TO_UINT32 (rc->Y); } //g_warning("FW: %d\tFH: %d", FrameWidth, FrameHeight); if ((FrameWidth <= 0) || (fmt->formatFlags & StringFormatFlagsNoWrap)) { pango_layout_set_width (layout, -1); //g_warning ("Setting width: %d", -1); } else { pango_layout_set_width (layout, FrameWidth * PANGO_SCALE); //g_warning ("Setting width: %d", FrameWidth * PANGO_SCALE); } if ((rc->Width != 0) && (rc->Height != 0) && ((fmt->formatFlags & StringFormatFlagsNoClip) == 0)) { // g_warning ("\tclip [%g %g %g %g]", rc->X, rc->Y, rc->Width, rc->Height); /* We do not call cairo_reset_clip because we want to take previous clipping into account */ /* Use rc instead of frame variables because this is pre-transform */ gdip_cairo_rectangle (graphics, rc->X, rc->Y, rc->Width, rc->Height, TRUE); cairo_clip (graphics->ct); } /* with GDI+ the API not the renderer makes the direction decision */ pango_layout_set_auto_dir (layout, FALSE); if (!(fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) != !(fmt->formatFlags & StringFormatFlagsDirectionVertical)) { pango_context_set_base_dir (context, PANGO_DIRECTION_WEAK_RTL); pango_layout_context_changed (layout); /* horizontal alignment */ switch (fmt->alignment) { case StringAlignmentNear: pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); break; case StringAlignmentCenter: pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); break; case StringAlignmentFar: pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); break; } } else { /* pango default base dir is WEAK_LTR, which is what we want */ /* horizontal alignment */ switch (fmt->alignment) { case StringAlignmentNear: pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); break; case StringAlignmentCenter: pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); break; case StringAlignmentFar: pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); break; } } #ifdef PANGO_VERSION_CHECK #if PANGO_VERSION_CHECK(1,16,0) if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { if (fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) { cairo_rotate (graphics->ct, M_PI/2.0); cairo_translate (graphics->ct, 0, -FrameHeight); pango_cairo_update_context (graphics->ct, context); } else { cairo_rotate (graphics->ct, 3.0*M_PI/2.0); cairo_translate (graphics->ct, -FrameWidth, 0); pango_cairo_update_context (graphics->ct, context); } /* only since Pango 1.16 */ pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO); pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_LINE); pango_layout_context_changed (layout); } #endif #endif /* TODO - StringFormatFlagsDisplayFormatControl scan and replace them ??? */ /* Trimming options seem to apply only to the end of the string - gdi+ will still wrap * with preference to word first, then character. Unfortunately, pango doesn't have * any way to differentiate wrapping behavior from trimming behavior that I could find */ pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); switch (fmt->trimming) { case StringTrimmingNone: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); break; case StringTrimmingCharacter: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); break; case StringTrimmingWord: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); break; case StringTrimmingEllipsisCharacter: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); if (!(fmt->formatFlags & StringFormatFlagsNoWrap)) pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE); break; case StringTrimmingEllipsisWord: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); if (!(fmt->formatFlags & StringFormatFlagsNoWrap)) pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE); break; case StringTrimmingEllipsisPath: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE); if (!(fmt->formatFlags & StringFormatFlagsNoWrap)) pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE); break; } /* some stuff can only be done by manipulating the attributes (but we can avoid this most of the time) */ if ((fmt->formatFlags & StringFormatFlagsNoFontFallback) || (font->style & (FontStyleUnderline | FontStyleStrikeout))) { list = gdip_get_layout_attributes (layout); /* StringFormatFlagsNoFontFallback */ if (fmt->formatFlags & StringFormatFlagsNoFontFallback) { PangoAttribute *attr = pango_attr_fallback_new (FALSE); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert (list, attr); } if (font->style & FontStyleUnderline) { PangoAttribute *attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert (list, attr); } if (font->style & FontStyleStrikeout) { PangoAttribute *attr = pango_attr_strikethrough_new (TRUE); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert (list, attr); } } if (fmt->numtabStops > 0) { float tabPosition; tabs = pango_tab_array_new (fmt->numtabStops, FALSE); tabPosition = fmt->firstTabOffset; for (i = 0; i < fmt->numtabStops; i++) { tabPosition += fmt->tabStops[i]; pango_tab_array_set_tab (tabs, i, PANGO_TAB_LEFT, (gint)min (tabPosition, PANGO_MAX) * PANGO_SCALE); } pango_layout_set_tabs (layout, tabs); pango_tab_array_free (tabs); } //g_warning ("length before ws removal: %d", length); trimSpace = (fmt->formatFlags & StringFormatFlagsMeasureTrailingSpaces) == 0; switch (fmt->hotkeyPrefix) { case HotkeyPrefixHide: /* we need to remove any accelerator from the string */ ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved); break; case HotkeyPrefixShow: /* optimization: is seems that we never see the hotkey when using an underline font */ if (font->style & FontStyleUnderline) { /* so don't bother drawing it (and simply add the '&' character) */ ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved); } else { /* find accelerator and add attribute to the next character (unless it's the prefix too) */ if (!list) list = gdip_get_layout_attributes (layout); ftext = gdip_process_string (text, length, 1, trimSpace, list, charsRemoved); } break; default: ftext = gdip_process_string (text, length, 0, trimSpace, NULL, charsRemoved); break; } length = ftext->len; //g_warning ("length after ws removal: %d", length); if (list) { pango_layout_set_attributes (layout, list); pango_attr_list_unref (list); } // g_warning("\tftext>%s< (%d)", ftext->str, -1); pango_layout_set_text (layout, ftext->str, ftext->len); GdipFree (text); g_string_free(ftext, TRUE); /* Trim the text after the last line for ease of counting lines/characters */ /* Also prevents drawing whole lines outside the boundaries if NoClip was specified */ /* In case of pre-existing clipping, use smaller of clip rectangle or our specified height */ if (FrameHeight > 0) { cairo_clip_extents (graphics->ct, &clipx1, &clipy1, &clipx2, &clipy2); if (clipy2 > 0 && !(fmt->formatFlags & StringFormatFlagsNoClip)) clipy2 = min (clipy2, FrameHeight + FrameY); else clipy2 = FrameHeight + FrameY; iter = pango_layout_get_iter (layout); do { if (iter == NULL) break; pango_layout_iter_get_line_yrange (iter, &y0, &y1); //g_warning("yrange: %d %d clipy2: %f", y0 / PANGO_SCALE, y1 / PANGO_SCALE, clipy2); /* StringFormatFlagsLineLimit */ if (((fmt->formatFlags & StringFormatFlagsLineLimit) && y1 / PANGO_SCALE > clipy2) || (y0 / PANGO_SCALE > clipy2)) { PangoLayoutLine *line = pango_layout_iter_get_line_readonly (iter); pango_layout_set_text (layout, pango_layout_get_text (layout), line->start_index); break; } } while (pango_layout_iter_next_line (iter)); pango_layout_iter_free (iter); } pango_layout_get_pixel_extents (layout, &ink, &logical); // g_warning ("\tlogical\t[x %d, y %d, w %d, h %d][x %d, y %d, w %d, h %d]", logical.x, logical.y, logical.width, logical.height, ink.x, ink.y, ink.width, ink.height); if ((fmt->formatFlags & StringFormatFlagsNoFitBlackBox) == 0) { /* By default don't allow overhang - ink space may be larger than logical space */ if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { box->X = min (ink.y, logical.y); box->Y = min (ink.x, logical.x); box->Height = max (ink.width, logical.width); box->Width = max (ink.height, logical.height); } else { box->X = min (ink.x, logical.x); box->Y = min (ink.y, logical.y); box->Height = max (ink.height, logical.height); box->Width = max (ink.width, logical.width); } } else { /* Allow overhang */ if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { box->X = logical.y; box->Y = logical.x; box->Height = logical.width; box->Width = logical.height; } else { box->X = logical.x; box->Y = logical.y; box->Height = logical.height; box->Width = logical.width; } } // g_warning ("\tbox\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height); /* vertical alignment*/ if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { switch (fmt->lineAlignment) { case StringAlignmentNear: break; case StringAlignmentCenter: box->X += (rc->Width - box->Width) / 2; break; case StringAlignmentFar: box->X += (rc->Width - box->Width); break; } } else { switch (fmt->lineAlignment) { case StringAlignmentNear: break; case StringAlignmentCenter: box->Y += (rc->Height - box->Height) / 2; break; case StringAlignmentFar: box->Y += (rc->Height - box->Height); break; } } // g_warning ("va-box\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height); pango_cairo_update_layout (graphics->ct, layout); return layout; }
void iupdrvDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, int w, int h, long color, const char* font, int flags, double text_orientation) { PangoLayout* fontlayout = (PangoLayout*)iupgtkGetPangoLayout(font); PangoAlignment alignment = PANGO_ALIGN_LEFT; GdkColor c; PangoContext* fontcontext = NULL; int layout_w = w, layout_h = h; int layout_center = flags & IUP_DRAW_LAYOUTCENTER; if (text_orientation && layout_center) iupDrawGetTextInnerBounds(w, h, text_orientation, &layout_w, &layout_h); iupgdkColorSet(&c, color); gdk_gc_set_rgb_fg_color(dc->pixmap_gc, &c); text = iupgtkStrConvertToSystemLen(text, &len); pango_layout_set_text(fontlayout, text, len); if (flags & IUP_DRAW_RIGHT) alignment = PANGO_ALIGN_RIGHT; else if (flags & IUP_DRAW_CENTER) alignment = PANGO_ALIGN_CENTER; if (flags & IUP_DRAW_WRAP) { pango_layout_set_width(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_w)); #ifdef PANGO_VERSION_CHECK #if PANGO_VERSION_CHECK(1,2,0) pango_layout_set_height(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_h)); #endif #endif } else if (flags & IUP_DRAW_ELLIPSIS) { pango_layout_set_width(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_w)); #ifdef PANGO_VERSION_CHECK #if PANGO_VERSION_CHECK(1,2,0) pango_layout_set_height(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_h)); #endif #endif pango_layout_set_ellipsize(fontlayout, PANGO_ELLIPSIZE_END); } pango_layout_set_alignment(fontlayout, alignment); if (flags & IUP_DRAW_CLIP) { GdkRectangle rect; rect.x = x; rect.y = y; rect.width = w; rect.height = h; gdk_gc_set_clip_rectangle(dc->pixmap_gc, &rect); } if (text_orientation) { PangoRectangle rect; PangoMatrix fontmatrix = PANGO_MATRIX_INIT; fontcontext = pango_layout_get_context(fontlayout); pango_matrix_rotate(&fontmatrix, text_orientation); pango_context_set_matrix(fontcontext, &fontmatrix); pango_layout_context_changed(fontlayout); pango_layout_get_pixel_extents(fontlayout, NULL, &rect); #ifdef PANGO_VERSION_CHECK #if PANGO_VERSION_CHECK(1,16,0) pango_matrix_transform_pixel_rectangle(&fontmatrix, &rect); #endif #endif /* Adjust the position considering the Pango rectangle transformed */ if (layout_center) { x += (w - rect.width) / 2; y += (h - rect.height) / 2; } else { x += (int)rect.x; y += (int)rect.y; } } gdk_draw_layout(dc->pixmap, dc->pixmap_gc, x, y, fontlayout); /* restore settings */ if ((flags & IUP_DRAW_WRAP) || (flags & IUP_DRAW_ELLIPSIS)) { pango_layout_set_width(fontlayout, -1); #ifdef PANGO_VERSION_CHECK #if PANGO_VERSION_CHECK(1,2,0) pango_layout_set_height(fontlayout, -1); #endif #endif } if (flags & IUP_DRAW_ELLIPSIS) pango_layout_set_ellipsize(fontlayout, PANGO_ELLIPSIZE_NONE); if (flags & IUP_DRAW_CLIP) gdk_gc_set_clip_region(dc->pixmap_gc, NULL); if (text_orientation) pango_context_set_matrix(fontcontext, NULL); }
/* * render functions */ static void begin_render(DiaRenderer *self, const Rectangle *update) { DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self); real onedu = 0.0; real lmargin = 0.0, tmargin = 0.0; gboolean paginated = renderer->surface && /* only with our own pagination, not GtkPrint */ cairo_surface_get_type (renderer->surface) == CAIRO_SURFACE_TYPE_PDF && !renderer->skip_show_page; if (renderer->surface && !renderer->cr) renderer->cr = cairo_create (renderer->surface); else g_assert (renderer->cr); /* remember current state, so we can start from new with every page */ cairo_save (renderer->cr); if (paginated && renderer->dia) { DiagramData *data = renderer->dia; /* Dia's paper.width already contains the scale, cairo needs it without * Similar for margins, Dia's without, but cairo wants them? */ real width = (data->paper.lmargin + data->paper.width * data->paper.scaling + data->paper.rmargin) * (72.0 / 2.54) + 0.5; real height = (data->paper.tmargin + data->paper.height * data->paper.scaling + data->paper.bmargin) * (72.0 / 2.54) + 0.5; /* "Changes the size of a PDF surface for the current (and * subsequent) pages." Pagination setup? */ cairo_pdf_surface_set_size (renderer->surface, width, height); lmargin = data->paper.lmargin / data->paper.scaling; tmargin = data->paper.tmargin / data->paper.scaling; } cairo_scale (renderer->cr, renderer->scale, renderer->scale); /* to ensure no clipping at top/left we need some extra gymnastics, * otherwise a box with a line witdh one one pixel might loose the * top/left border as in bug #147386 */ ensure_minimum_one_device_unit (renderer, &onedu); if (update && paginated) { cairo_rectangle (renderer->cr, lmargin, tmargin, update->right - update->left, update->bottom - update->top); cairo_clip (renderer->cr); cairo_translate (renderer->cr, -update->left + lmargin, -update->top + tmargin); } else cairo_translate (renderer->cr, -renderer->dia->extents.left + onedu, -renderer->dia->extents.top + onedu); /* no more blurred UML diagrams */ cairo_set_antialias (renderer->cr, CAIRO_ANTIALIAS_NONE); /* clear background */ if (renderer->with_alpha) { cairo_set_operator (renderer->cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (renderer->cr, renderer->dia->bg_color.red, renderer->dia->bg_color.green, renderer->dia->bg_color.blue, 0.0); } else { cairo_set_source_rgba (renderer->cr, renderer->dia->bg_color.red, renderer->dia->bg_color.green, renderer->dia->bg_color.blue, 1.0); } cairo_paint (renderer->cr); if (renderer->with_alpha) { /* restore to default drawing */ cairo_set_operator (renderer->cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (renderer->cr, renderer->dia->bg_color.red, renderer->dia->bg_color.green, renderer->dia->bg_color.blue, 1.0); } #ifdef HAVE_PANGOCAIRO_H if (!renderer->layout) renderer->layout = pango_cairo_create_layout (renderer->cr); #endif cairo_set_fill_rule (renderer->cr, CAIRO_FILL_RULE_EVEN_ODD); #if 0 /* try to work around bug #341481 - no luck */ { cairo_font_options_t *fo = cairo_font_options_create (); cairo_get_font_options (renderer->cr, fo); /* try to switch off kerning */ cairo_font_options_set_hint_style (fo, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (fo, CAIRO_HINT_METRICS_OFF); cairo_set_font_options (renderer->cr, fo); cairo_font_options_destroy (fo); #ifdef HAVE_PANGOCAIRO_H pango_cairo_update_context (renderer->cr, pango_layout_get_context (renderer->layout)); pango_layout_context_changed (renderer->layout); #endif } #endif DIAG_STATE(renderer->cr) }
static VALUE rg_context_changed(VALUE self) { pango_layout_context_changed(_SELF(self)); return Qnil; }
static void gtk_plot_gdk_draw_string (GtkPlotPC *pc, gint tx, gint ty, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font_name, gint font_height, GtkJustification just, const gchar *text) { GdkGC *gc; GList *family = NULL; gint x0, y0; gint old_width, old_height; gboolean bold, italic; gint fontsize; gint ascent, descent; gint numf; gint width, height; gint x, y; gint i; PangoFontDescription *font = NULL, *latin_font = NULL; GtkPSFont *psfont, *base_psfont, *latin_psfont; gchar subs[2], insert_char; const gchar *aux = text; const gchar *lastchar = text; const gchar *wtext = text; const gchar *xaux = text; gchar new_text[strlen(text)+1]; gchar num[4]; PangoRectangle rect; PangoFontMetrics *metrics = NULL; PangoLayout *layout = NULL; gint real_x, real_y, real_width, real_height; GdkColor real_fg = *fg; GdkColor real_bg = *bg; PangoMatrix matrix = PANGO_MATRIX_INIT; PangoContext *context = GTK_PLOT_GDK(pc)->context; GdkDrawable *drawable = GTK_PLOT_GDK(pc)->drawable; gint sign_x = 1, sign_y = 0; if(!GTK_PLOT_GDK(pc)->drawable) return; if(!GTK_PLOT_GDK(pc)->gc) return; if(!text || strlen(text) == 0) return; gc = GTK_PLOT_GDK(pc)->gc; layout = GTK_PLOT_GDK(pc)->layout; if(!gc) return; gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent); if(height == 0 || width == 0) return; old_width = width; old_height = height; if(angle == 90 || angle == 270) { old_width = height; old_height = width; } switch(angle){ case 90: sign_x = 0; sign_y = -1; break; case 180: sign_x = -1; sign_y = 0; break; case 270: sign_x = 0; sign_y = 1; break; case 0: default: sign_x = 1; sign_y = 0; break; } switch(just){ case GTK_JUSTIFY_LEFT: switch(angle){ case 0: ty -= ascent; break; case 90: ty -= height; tx -= ascent; break; case 180: tx -= width; ty -= descent; break; case 270: tx -= descent; break; } break; case GTK_JUSTIFY_RIGHT: switch(angle){ case 0: tx -= width; ty -= ascent; break; case 90: tx -= ascent; ty += height; break; case 180: tx += width; ty -= descent; break; case 270: tx -= descent; break; } break; case GTK_JUSTIFY_CENTER: default: switch(angle){ case 0: tx -= width / 2.; ty -= ascent; break; case 90: tx -= ascent; ty += height / 2.; break; case 180: tx += width / 2.; ty -= descent; break; case 270: tx -= descent; ty -= height / 2.; break; } } real_x = tx; real_y = ty; real_width = width; real_height = height; pango_matrix_rotate (&matrix, angle); pango_context_set_matrix (context, &matrix); pango_layout_context_changed (layout); if(!transparent){ gdk_gc_set_foreground(gc, &real_bg); gdk_draw_rectangle(drawable, gc, TRUE, tx, ty, old_width, old_height); } /* TEST */ /* gdk_draw_rectangle(text_pixmap, gc, FALSE, 0, 0, old_width-1, old_height-1); */ gtk_psfont_get_families(&family, &numf); base_psfont = psfont = gtk_psfont_get_by_name(font_name); font = gtk_psfont_get_font_description(psfont, font_height); italic = psfont->italic; bold = psfont->bold; fontsize = font_height; x0 = x = 0; y0 = y = 0; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); if(latin_font) pango_font_description_free(latin_font); latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } else { latin_psfont = NULL; latin_font = NULL; } gdk_gc_set_foreground(gc, &real_fg); aux = text; while(aux && *aux != '\0' && *aux != '\n'){ if(*aux == '\\'){ aux = g_utf8_next_char(aux); switch(*aux){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': psfont = gtk_psfont_get_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); aux = g_utf8_next_char(aux); break; case '8': case 'g': psfont = gtk_psfont_get_by_family("Symbol", italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); aux = g_utf8_next_char(aux); break; case 'B': bold = TRUE; psfont = gtk_psfont_get_by_family(psfont->family, italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(latin_font){ latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); if(latin_font) pango_font_description_free(latin_font); latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case 'x': xaux = aux + 1; for (i=0; i<3; i++){ if (xaux[i] >= '0' && xaux[i] <= '9') num[i] = xaux[i]; else break; } if (i < 3){ aux = g_utf8_next_char(aux); break; } num[3] = '\0'; insert_char = (gchar)atoi(num); subs[0] = insert_char; subs[1] = '\0'; pango_layout_set_font_description(layout, font); pango_layout_set_text(layout, subs, 1); pango_layout_get_extents(layout, NULL, &rect); x += sign_x*PANGO_PIXELS(rect.width); y += sign_y*PANGO_PIXELS(rect.width); aux += 4; lastchar = aux - 1; break; case 'i': italic = TRUE; psfont = gtk_psfont_get_by_family(psfont->family, italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); if(latin_font) pango_font_description_free(latin_font); latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case 'S': case '^': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(metrics) pango_font_metrics_unref(metrics); metrics = pango_context_get_metrics(pango_layout_get_context(layout), font, pango_context_get_language(pango_layout_get_context(layout))); if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } if(angle == 180) y = y0 + fontsize; else if(angle == 270) x = x0 + sign_y*fontsize; aux = g_utf8_next_char(aux); break; case 's': case '_': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(metrics) pango_font_metrics_unref(metrics); metrics = pango_context_get_metrics(pango_layout_get_context(layout), font, pango_context_get_language(pango_layout_get_context(layout))); if(angle == 0) y = y0 + fontsize; else if(angle == 90) x = x0 - sign_y*fontsize; if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case '+': fontsize += 3; y -= sign_x*3; x += sign_y*3; pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case '-': fontsize -= 3; y += sign_x*3; x -= sign_y*3; pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case 'N': psfont = base_psfont; fontsize = font_height; pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(angle == 0 || angle == 180) y = y0; else x = x0; italic = psfont->italic; bold = psfont->bold; aux = g_utf8_next_char(aux); break; case 'b': if (lastchar) { const gchar *aux2 = lastchar; gint i = g_utf8_prev_char(lastchar) != --aux2 ? 2 : 1; pango_layout_set_text(layout, lastchar, i); pango_layout_get_extents(layout, NULL, &rect); x -= sign_x*PANGO_PIXELS(rect.width); y -= sign_y*PANGO_PIXELS(rect.width); if (lastchar == wtext) lastchar = NULL; else lastchar = g_utf8_prev_char(lastchar); } else { pango_layout_set_text(layout, "X", 1); pango_layout_get_extents(layout, NULL, &rect); x -= sign_x*PANGO_PIXELS(rect.width); y -= sign_y*PANGO_PIXELS(rect.width); } aux = g_utf8_next_char(aux); break; default: if(aux && *aux != '\0' && *aux !='\n'){ gint new_width = 0; new_width = drawstring(pc, drawable, gc, angle, tx+x, ty+y, psfont, fontsize, aux); x += sign_x * new_width; y += sign_y * new_width; lastchar = aux; aux = g_utf8_next_char(aux); } break; } } else { gint new_len = 0; gint new_width = 0; lastchar = aux; while(aux && *aux != '\0' && *aux !='\n' && *aux != '\\'){ xaux = aux; new_len += g_utf8_next_char(aux) != ++xaux ? 2 : 1; aux = g_utf8_next_char(aux); } xaux = lastchar; for(i = 0; i < new_len; i++) new_text[i] = *xaux++; new_text[new_len] = '\0'; new_width = drawstring(pc, drawable, gc, angle, tx+x, ty+y, psfont, fontsize, new_text); x += sign_x * new_width; y += sign_y * new_width; lastchar = aux; } } pango_font_description_free(font); if(latin_font) pango_font_description_free(latin_font); if(metrics) pango_font_metrics_unref(metrics); /* border */ gdk_gc_set_foreground(gc, &real_fg); gtk_plot_pc_set_dash(pc, 0, NULL, 0); gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0); switch(border){ case GTK_PLOT_BORDER_SHADOW: gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space + shadow_width, ty + height + border_space, width + 2 * border_space, shadow_width); gtk_plot_pc_draw_rectangle(pc, TRUE, tx + width + border_space, ty - border_space + shadow_width, shadow_width, height + 2 * border_space); case GTK_PLOT_BORDER_LINE: gtk_plot_pc_draw_rectangle(pc, FALSE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); case GTK_PLOT_BORDER_NONE: default: break; } return; }
//----------------------------------------------------------------------------- void t_display_rysuj_siatke_czas (T_Display *w) { int wys ; char ctmp [20] ; wys = w->canvas->allocation.height ; // kolor siatki i opisow GdkGC *gc = gdk_gc_new (GTK_LAYOUT(w->canvas)->bin_window); GdkColor color ; color.red = 0; color.green = 40000; color.blue = 0; gdk_gc_set_rgb_fg_color(gc,&color) ; time_t hours = w->last_time - w->last_time % w->time_step ; int dzialka_godz = w->time_step / 3600 ; //printf ("%d %d %d\n",hours, dzialka_godz, w->last_time % w->time_step) ; if (w->time_step > 60*60) { // dla dzialki powyzej godziny utrzymac polnoc :) hours = full_hour(w->last_time) ; while ( ((get_hour(hours) % dzialka_godz) != 0) && (hours > (w->last_time - w->time_range)) ) { hours -= 3600 ; // czasami nie pokazuje najpozniejszej godziny dla dzialki 3h // pewnie przez jakies dziwne zjawiska z czasem (lata przestepne ?) } ; } ; //printf ("%d\n",hours) ; int x_hours ; PangoLayout *etykieta ; int et_szer, et_wys ; int label_x, label_y ; while (hours > (w->last_time - w->time_range)) { x_hours = time_to_pixel_x(hours, w) ; //snprintf (&(ctmp[0]), 20, "%.2d:%.2d", get_hour(hours), get_minute(hours)) ; gen_time_label_string(&(ctmp[0]), 20, hours, w) ; etykieta = gtk_widget_create_pango_layout (w->canvas,ctmp); pango_layout_get_pixel_size (etykieta, &et_szer, &et_wys) ; label_x = x_hours-et_szer/2 ; label_y = et_wys+LABEL_MARGIN/2 ; PangoMatrix matrix = PANGO_MATRIX_INIT; if (w->x_labels_vert == TRUE) { pango_matrix_rotate (&matrix, 90.); label_x = x_hours - (et_wys)/2 ; label_y = et_szer + LABEL_MARGIN ; } ; pango_context_set_matrix (pango_layout_get_context(etykieta), &matrix); pango_layout_context_changed(etykieta) ; // rysowanie dzialek i etykiet gdk_draw_layout (GTK_LAYOUT(w->canvas)->bin_window, //w->canvas->style->fg_gc[GTK_WIDGET_STATE (w->canvas)], gc, label_x, wys-label_y - w->legend_height, etykieta) ; gdk_draw_line (GTK_LAYOUT(w->canvas)->bin_window, //w->canvas->style->fg_gc[GTK_WIDGET_STATE (w->canvas)], gc, x_hours,wys-w->y_pixel_offset,x_hours,wys-wys) ; // pogrubienie wybranych dzialek if ((get_seconds(hours) == 0) && (get_minute(hours) == 0) && (get_hour(hours) == 0) ) { gdk_draw_line (GTK_LAYOUT(w->canvas)->bin_window, //w->canvas->style->fg_gc[GTK_WIDGET_STATE (w->canvas)], gc, x_hours+1,wys-w->y_pixel_offset,x_hours+1,wys-wys) ; } ; g_object_unref(etykieta) ; hours -= w->time_step ; } ; g_object_unref(gc) ; } ;
cairo_surface_t* render_text_to_surface (gchar* text, gint width, gint height, const cairo_font_options_t* font_opts, gdouble dpi) { cairo_surface_t* surface; cairo_t* cr; PangoFontDescription* desc; PangoLayout* layout; // sanity check if (!text || width <= 0 || height <= 0) return NULL; // create surface surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) return NULL; // create context cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return NULL; } // clear context cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); // layout = pango_cairo_create_layout (cr); desc = pango_font_description_new (); pango_font_description_set_size (desc, 12 * PANGO_SCALE); pango_font_description_set_family_static (desc, "Candara"); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_wrap (layout, PANGO_WRAP_WORD); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_width (layout, width * PANGO_SCALE); pango_layout_set_height (layout, height * PANGO_SCALE); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); // print and layout string (pango-wise) pango_layout_set_text (layout, text, -1); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts); pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi); pango_layout_context_changed (layout); // draw pango-text to our cairo-context cairo_move_to (cr, 0.0f, 0.0f); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); // this call leaks 3803 bytes, I've no idea how to fix that pango_cairo_show_layout (cr, layout); // clean up g_object_unref (layout); cairo_destroy (cr); return surface; }
/* Redraw the ruler */ static gboolean histo_expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) { histoDrawing_t *drawing = (histoDrawing_t*)user_data; TimeWindow time_window = lttvwindow_get_time_window(drawing->histo_control_flow_data->tab); gchar text[255]; PangoContext *context; PangoLayout *layout; PangoFontDescription *FontDesc; PangoRectangle ink_rect; gint global_width=0; GdkColor foreground = { 0, 0, 0, 0 }; GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; LttTime window_end = time_window.end_time; LttTime half_width = ltt_time_div(time_window.time_width,2.0); LttTime window_middle = ltt_time_add(half_width, time_window.start_time); g_debug("ruler expose event"); gdk_draw_rectangle (drawing->ruler->window, drawing->ruler->style->white_gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_butt, event->area.x, 1, event->area.x + event->area.width, 1); snprintf(text, 255, "%lus\n%luns", time_window.start_time.tv_sec, time_window.start_time.tv_nsec); layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); context = pango_layout_get_context(layout); FontDesc = pango_context_get_font_description(context); pango_font_description_set_size(FontDesc, 6*PANGO_SCALE); pango_layout_context_changed(layout); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_width += ink_rect.width; gdk_draw_layout_with_colors(drawing->ruler->window, drawing->ruler_gc_butt, 0, 6, layout, &foreground, &background); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_round, 1, 1, 1, 7); snprintf(text, 255, "%lus\n%luns", window_end.tv_sec, window_end.tv_nsec); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_width += ink_rect.width; if(global_width <= drawing->ruler->allocation.width) { gdk_draw_layout_with_colors(drawing->ruler->window, drawing->ruler_gc_butt, drawing->ruler->allocation.width - ink_rect.width, 6, layout, &foreground, &background); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_butt, drawing->ruler->allocation.width-1, 1, drawing->ruler->allocation.width-1, 7); } snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec, window_middle.tv_nsec); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_width += ink_rect.width; if(global_width <= drawing->ruler->allocation.width) { gdk_draw_layout_with_colors(drawing->ruler->window, drawing->ruler_gc_butt, (drawing->ruler->allocation.width - ink_rect.width)/2, 6, layout, &foreground, &background); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_butt, drawing->ruler->allocation.width/2, 1, drawing->ruler->allocation.width/2, 7); } g_object_unref(layout); return FALSE; }
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { DocInfo *dinfo = user_data; GeanyEditor *editor; cairo_t *cr; gdouble width, height; gdouble x = 0.0, y = 0.0; /*gint layout_h;*/ gint count; GString *str; if (dinfo == NULL || page_nr >= dinfo->n_pages) return; editor = dinfo->doc->editor; if (dinfo->n_pages > 0) { gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages; gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text); g_free(text); } #ifdef GEANY_PRINT_DEBUG geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d", page_nr, dinfo->n_pages, dinfo->lines_per_page); #endif str = g_string_sized_new(256); cr = gtk_print_context_get_cairo_context(context); width = gtk_print_context_get_width(context); height = gtk_print_context_get_height(context); cairo_set_source_rgb(cr, 0, 0, 0); #ifdef GEANY_PRINT_DEBUG cairo_set_line_width(cr, 0.2); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); #endif cairo_move_to(cr, 0, 0); pango_layout_set_width(dinfo->layout, width * PANGO_SCALE); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT); pango_layout_set_ellipsize(dinfo->layout, FALSE); pango_layout_set_justify(dinfo->layout, FALSE); if (printing_prefs.print_page_header) add_page_header(dinfo, cr, width, page_nr); count = 0; /* the actual line counter for the current page, might be different from * dinfo->cur_line due to possible line breaks */ while (count < dinfo->lines_per_page) { gchar c = 'a'; gint style = -1; PangoAttrList *layout_attr; PangoAttribute *attr; gint colours[3] = { 0 }; gboolean add_linenumber = TRUE; gboolean at_eol; while (count < dinfo->lines_per_page && c != '\0') { at_eol = FALSE; g_string_erase(str, 0, str->len); /* clear the string */ /* line numbers */ if (printing_prefs.print_line_numbers && add_linenumber) { /* if we had a wrapped line on the last page which needs to be continued, don't * add a line number */ if (dinfo->long_line) { add_linenumber = FALSE; } else { gchar *line_number = NULL; gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1); gchar *fill = g_strnfill( dinfo->max_line_number_margin - cur_line_number_margin - 1, ' '); line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1); g_string_append(str, line_number); dinfo->cur_line++; /* increase document line */ add_linenumber = FALSE; style = STYLE_LINENUMBER; c = 'a'; /* dummy value */ g_free(fill); g_free(line_number); } } /* data */ else { style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos); c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c == '\0' || style == -1) { /* if c gets 0, we are probably out of document boundaries, * so stop to break out of outer loop */ count = dinfo->lines_per_page; break; } dinfo->cur_pos++; /* convert tabs to spaces which seems to be better than using Pango tabs */ if (c == '\t') { gint tab_width = sci_get_tab_width(editor->sci); gchar *s = g_strnfill(tab_width, ' '); g_string_append(str, s); g_free(s); } /* don't add line breaks, they are handled manually below */ else if (c == '\r' || c == '\n') { gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); at_eol = TRUE; if (c == '\r' && c_next == '\n') dinfo->cur_pos++; /* skip LF part of CR/LF */ } else { g_string_append_c(str, c); /* finally add the character */ /* handle UTF-8: since we add char by char (better: byte by byte), we need to * keep UTF-8 characters together(e.g. two bytes for one character) * the input is always UTF-8 and c is signed, so all non-Ascii * characters are less than 0 and consist of all bytes less than 0. * style doesn't change since it is only one character with multiple bytes. */ while (c < 0) { c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c < 0) { /* only add the byte when it is part of the UTF-8 character * otherwise we could add e.g. a '\n' and it won't be visible in the * printed document */ g_string_append_c(str, c); dinfo->cur_pos++; } } } } if (! at_eol) { /* set text */ pango_layout_set_text(dinfo->layout, str->str, -1); /* attributes */ layout_attr = pango_attr_list_new(); /* foreground colour */ get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]); attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]); ADD_ATTR(layout_attr, attr); /* background colour */ get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]); attr = pango_attr_background_new(colours[0], colours[1], colours[2]); ADD_ATTR(layout_attr, attr); /* bold text */ if (dinfo->styles[style][BOLD]) { attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD); ADD_ATTR(layout_attr, attr); } /* italic text */ if (dinfo->styles[style][ITALIC]) { attr = pango_attr_style_new(PANGO_STYLE_ITALIC); ADD_ATTR(layout_attr, attr); } pango_layout_set_attributes(dinfo->layout, layout_attr); pango_layout_context_changed(dinfo->layout); pango_attr_list_unref(layout_attr); } cairo_get_current_point(cr, &x, &y); /* normal line break at eol character in document */ if (at_eol) { /*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/ /*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/ cairo_move_to(cr, 0, y + dinfo->line_height); count++; /* we added a new document line so request a new line number */ add_linenumber = TRUE; } else { gint x_offset = 0; /* maybe we need to force a line break because of too long line */ if (x >= (width - dinfo->font_width)) { /* don't start the line at horizontal origin because we need to skip the * line number margin */ if (printing_prefs.print_line_numbers) { x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width; } /*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/ /*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/ /* this is faster but not exactly the same as above */ cairo_move_to(cr, x_offset, y + dinfo->line_height); cairo_get_current_point(cr, &x, &y); count++; } if (count < dinfo->lines_per_page) { /* str->len is counted in bytes not characters, so use g_utf8_strlen() */ x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width); if (dinfo->long_line && count == 0) { x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width; dinfo->long_line = FALSE; } pango_cairo_show_layout(cr, dinfo->layout); cairo_move_to(cr, x + x_offset, y); } else /* we are on a wrapped line but we are out of lines on this page, so continue * the current line on the next page and remember to continue in current line */ dinfo->long_line = TRUE; } } } if (printing_prefs.print_line_numbers) { /* print a thin line between the line number margin and the data */ gint y_start = 0; if (printing_prefs.print_page_header) y_start = (dinfo->line_height * 3) - 2; /* "- 2": to connect the line number line to * the page header frame */ cairo_set_line_width(cr, 0.3); cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start); cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y + dinfo->line_height); /* y is last added line, we reuse it */ cairo_stroke(cr); } if (printing_prefs.print_page_numbers) { gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1); pango_layout_set_markup(dinfo->layout, line, -1); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER); cairo_move_to(cr, 0, height - dinfo->line_height); pango_cairo_show_layout(cr, dinfo->layout); g_free(line); #ifdef GEANY_PRINT_DEBUG cairo_set_line_width(cr, 0.3); cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height)); cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height)); cairo_stroke(cr); #endif } g_string_free(str, TRUE); }
void gnm_rendered_value_remeasure (GnmRenderedValue *rv) { if (rv->rotation) { GnmRenderedRotatedValue *rrv = (GnmRenderedRotatedValue *)rv; PangoContext *context = pango_layout_get_context (rv->layout); double sin_a, abs_sin_a, cos_a; int sdx = 0; int x0 = 0, x1 = 0; PangoLayoutIter *iter; int l = 0; int lwidth; sin_a = rrv->rotmat.xy; abs_sin_a = fabs (sin_a); cos_a = rrv->rotmat.xx; pango_context_set_matrix (context, &rrv->rotmat); pango_layout_context_changed (rv->layout); rrv->linecount = pango_layout_get_line_count (rv->layout); rrv->lines = g_new (struct GnmRenderedRotatedValueInfo, rrv->linecount); pango_layout_get_size (rv->layout, &lwidth, NULL); rv->layout_natural_height = 0; iter = pango_layout_get_iter (rv->layout); do { PangoRectangle logical; int x, dx, dy, indent; int h, ytop, ybot, baseline; pango_layout_iter_get_line_extents (iter, NULL, &logical); pango_layout_iter_get_line_yrange (iter, &ytop, &ybot); baseline = pango_layout_iter_get_baseline (iter); indent = logical.x; if (sin_a < 0) indent -= lwidth; if (l == 0 && rv->noborders) sdx = (int)(baseline * sin_a - ybot / sin_a); dx = sdx + (int)(ybot / sin_a + indent * cos_a); dy = (int)((baseline - ybot) * cos_a - indent * sin_a); rrv->lines[l].dx = dx; rrv->lines[l].dy = dy; /* Left edge. */ x = dx - (int)((baseline - ytop) * sin_a); x0 = MIN (x0, x); /* Right edge. */ x = dx + (int)(logical.width * cos_a + (ybot - baseline) * sin_a); x1 = MAX (x1, x); h = logical.width * abs_sin_a + logical.height * cos_a; if (h > rv->layout_natural_height) rv->layout_natural_height = h; l++; } while (pango_layout_iter_next_line (iter)); pango_layout_iter_free (iter); rv->layout_natural_width = x1 - x0; if (sin_a < 0) { int dx = rv->layout_natural_width; for (l = 0; l < rrv->linecount; l++) rrv->lines[l].dx += dx; } for (l = 0; l < rrv->linecount; l++) rrv->lines[l].dy += rv->layout_natural_height; #if 0 g_print ("Natural size: %d x %d\n", rv->layout_natural_width, rv->layout_natural_height); #endif pango_context_set_matrix (context, NULL); pango_layout_context_changed (rv->layout); } else
static void draw_string(DiaRenderer *self, const char *text, Point *pos, Alignment alignment, Color *color) { DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self); int len = strlen(text); DIAG_NOTE(g_message("draw_string(%d) %f,%f %s", len, pos->x, pos->y, text)); if (len < 1) return; /* shouldn't this be handled by Dia's core ? */ cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0); #ifdef HAVE_PANGOCAIRO_H cairo_save (renderer->cr); /* alignment calculation done by pangocairo? */ pango_layout_set_alignment (renderer->layout, alignment == ALIGN_CENTER ? PANGO_ALIGN_CENTER : alignment == ALIGN_RIGHT ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT); pango_layout_set_text (renderer->layout, text, len); { PangoLayoutIter *iter = pango_layout_get_iter(renderer->layout); int bline = pango_layout_iter_get_baseline(iter); /* although we give the alignment above we need to adjust the start point */ PangoRectangle extents; int shift; pango_layout_iter_get_line_extents (iter, NULL, &extents); shift = alignment == ALIGN_CENTER ? PANGO_RBEARING(extents)/2 : alignment == ALIGN_RIGHT ? PANGO_RBEARING(extents) : 0; cairo_move_to (renderer->cr, pos->x - (double)shift / PANGO_SCALE, pos->y - (double)bline / PANGO_SCALE); pango_layout_iter_free (iter); } /* does this hide bug #341481? */ pango_cairo_update_context (renderer->cr, pango_layout_get_context (renderer->layout)); pango_layout_context_changed (renderer->layout); pango_cairo_show_layout (renderer->cr, renderer->layout); cairo_restore (renderer->cr); #else /* using the 'toy API' */ { cairo_text_extents_t extents; double x = 0, y = 0; cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0); cairo_text_extents (renderer->cr, text, &extents); y = pos->y; /* ?? */ switch (alignment) { case ALIGN_LEFT: x = pos->x; break; case ALIGN_CENTER: x = pos->x - extents.width / 2 + +extents.x_bearing; break; case ALIGN_RIGHT: x = pos->x - extents.width + extents.x_bearing; break; } cairo_move_to (renderer->cr, x, y); cairo_show_text (renderer->cr, text); } #endif DIAG_STATE(renderer->cr) }
/* * render functions */ static void begin_render(DiaRenderer *self) { DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self); if (renderer->surface) renderer->cr = cairo_create (renderer->surface); else g_assert (renderer->cr); cairo_scale (renderer->cr, renderer->scale, renderer->scale); cairo_translate (renderer->cr, -renderer->dia->extents.left, -renderer->dia->extents.top); /* clear background */ if (renderer->with_alpha) { cairo_set_operator (renderer->cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (renderer->cr, renderer->dia->bg_color.red, renderer->dia->bg_color.green, renderer->dia->bg_color.blue, 0.0); } else { cairo_set_source_rgba (renderer->cr, renderer->dia->bg_color.red, renderer->dia->bg_color.green, renderer->dia->bg_color.blue, 1.0); } cairo_paint (renderer->cr); if (renderer->with_alpha) { /* restore to default drawing */ cairo_set_operator (renderer->cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (renderer->cr, renderer->dia->bg_color.red, renderer->dia->bg_color.green, renderer->dia->bg_color.blue, 1.0); } #ifdef HAVE_PANGOCAIRO_H if (!renderer->layout) renderer->layout = pango_cairo_create_layout (renderer->cr); #endif cairo_set_fill_rule (renderer->cr, CAIRO_FILL_RULE_EVEN_ODD); #if 0 /* try to work around bug #341481 - no luck */ { cairo_font_options_t *fo = cairo_font_options_create (); cairo_get_font_options (renderer->cr, fo); /* try to switch off kerning */ cairo_font_options_set_hint_style (fo, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (fo, CAIRO_HINT_METRICS_OFF); cairo_set_font_options (renderer->cr, fo); cairo_font_options_destroy (fo); #ifdef HAVE_PANGOCAIRO_H pango_cairo_update_context (renderer->cr, pango_layout_get_context (renderer->layout)); pango_layout_context_changed (renderer->layout); #endif } #endif DIAG_STATE(renderer->cr) }
void render_text(GdkDrawable *da, GdkGC *gc, int x, int y, double angle, const char *s, const char *font, double xalign, double yalign, int xmax, int ymax) { GdkScreen *screen; PangoRenderer *renderer; PangoContext *context; PangoLayout *layout; PangoFontDescription *desc; int width, height; PangoMatrix m = PANGO_MATRIX_INIT; double f_min, f; /* set up the renderer */ screen = gdk_drawable_get_screen(da); renderer = gdk_pango_renderer_get_default(screen); gdk_pango_renderer_set_drawable(GDK_PANGO_RENDERER(renderer), da); gdk_pango_renderer_set_gc(GDK_PANGO_RENDERER(renderer), gc); /* start preparing the layout */ context = gdk_pango_context_get_for_screen(screen); layout = pango_layout_new(context); pango_layout_set_text(layout, s, -1); /* apply the font */ desc = pango_font_description_from_string(font); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); /* align and position the text */ pango_layout_get_size(layout, &width, &height); f_min = 1.0; if (xmax) { f = xmax/((double) width/PANGO_SCALE); if (f < f_min) f_min = f; } if (ymax) { f = ymax/((double) height/PANGO_SCALE); if (f < f_min) f_min = f; } if (f_min < MIN_FONT_SCALE) f_min = MIN_FONT_SCALE; pango_matrix_translate(&m, x, y); pango_matrix_rotate(&m, angle); pango_matrix_translate(&m, -xalign*f_min*width/PANGO_SCALE, (yalign-1)*f_min*height/PANGO_SCALE); pango_matrix_scale(&m, f_min, f_min); pango_context_set_matrix(context, &m); pango_layout_context_changed(layout); pango_renderer_draw_layout(renderer, layout, 0, 0); /* clean up renderer */ gdk_pango_renderer_set_drawable(GDK_PANGO_RENDERER(renderer), NULL); gdk_pango_renderer_set_gc(GDK_PANGO_RENDERER(renderer), NULL); /* free objects */ g_object_unref(layout); g_object_unref(context); }
void * fontmng_create(int size, UINT type, const TCHAR *fontface) { char buf[256]; _FNTMNG fnt; FNTMNG fntp; gchar *fontname_utf8; int fontalign; int allocsize; GdkColormap *cmap; GdkColor color; gboolean rv; if (size < 0) { size = -size; } if (size < 6) { size = 6; } else if (size > 128) { size = 128; } g_snprintf(buf, sizeof(buf), "%s %s %s %d", fontface ? (char *)fontface : fontname, (type & FDAT_BOLD) ? "bold" : "medium", (type & FDAT_PROPORTIONAL) ? "" : "", size); fontname_utf8 = g_locale_to_utf8(buf, -1, NULL, NULL, NULL); if (fontname_utf8 == NULL) { return NULL; } fnt.desc = pango_font_description_from_string(fontname_utf8); g_free(fontname_utf8); if (fnt.desc == NULL) { return NULL; } cmap = gtk_widget_get_colormap(GTK_WIDGET(main_window)); memset(&color, 0, sizeof(color)); rv = gdk_colormap_alloc_color(cmap, &color, FALSE, FALSE); if (rv) { fnt.black_pixel = color.pixel; } else { fnt.black_pixel = 0; } fnt.layout = gtk_widget_create_pango_layout(main_window, NULL); pango_layout_set_font_description(fnt.layout, fnt.desc); pango_layout_context_changed(fnt.layout); fnt.size = size; fnt.type = type; fnt.rect.x = fnt.rect.y = 0; fnt.rect.width = size + 1; fnt.rect.height = size + 1; fontalign = sizeof(_FNTDAT) + (fnt.rect.width * fnt.rect.height); fontalign = roundup(fontalign, 4); allocsize = sizeof(_FNTMNG); allocsize += fontalign; fnt.backsurf = gdk_pixmap_new(main_window->window, fnt.rect.width, fnt.rect.height, -1); fntp = _MALLOC(allocsize, "fontmng"); if (fntp) { memset(fntp, 0, allocsize); *fntp = fnt; } else { pango_font_description_free(fnt.desc); } return fntp; }
//------------------------------------------------------------------------------ // // Temperatura // //----------------------------------------------------------------------------- void t_display_rysuj_siatke_temp (T_Display *w) { int i_tmp ; int tmp_pixel ; int wys = w->canvas->allocation.height ; char ctmp [16] ; PangoLayout *etykieta ; int et_szer, et_wys ; int label_x, label_y ; PangoMatrix matrix = PANGO_MATRIX_INIT; // kolor siatki i opisow GdkGC *gc = gdk_gc_new (GTK_LAYOUT(w->canvas)->bin_window); GdkColor color ; color.red = 0; color.green = 40000; color.blue = 0; gdk_gc_set_rgb_fg_color(gc,&color) ; // najwyzsza wartosc dzialki i_tmp = w->temp_max - (w->temp_max % w->temp_step) ; while (i_tmp >= w->temp_min) { tmp_pixel = temp_to_pixel_y(i_tmp,w) ; // rysuj dzialke gdk_draw_line (GTK_LAYOUT(w->canvas)->bin_window, //w->canvas->style->fg_gc[GTK_WIDGET_STATE (w->canvas)], gc, w->x_pixel_offset, wys - tmp_pixel, w->canvas->allocation.width, wys- tmp_pixel); if (i_tmp == 0) { // ewentualne pogrubienie, tylko dla 0 stopni gdk_draw_line (GTK_LAYOUT(w->canvas)->bin_window, //w->canvas->style->fg_gc[GTK_WIDGET_STATE (w->canvas)], gc, w->x_pixel_offset, wys - tmp_pixel-1, w->canvas->allocation.width, wys- tmp_pixel-1); } ; // etykieta snprintf (&(ctmp[0]), 16, "%d", i_tmp) ; etykieta = gtk_widget_create_pango_layout (w->canvas,ctmp); pango_context_set_matrix (pango_layout_get_context(etykieta), &matrix); pango_layout_context_changed(etykieta) ; pango_layout_get_pixel_size (etykieta, &et_szer, &et_wys) ; label_x = LABEL_MARGIN ; label_y = tmp_pixel + (et_wys)/2 ; gdk_draw_layout (GTK_LAYOUT(w->canvas)->bin_window, //w->canvas->style->fg_gc[GTK_WIDGET_STATE (w->canvas)], gc, label_x, wys-label_y, etykieta) ; g_object_unref(etykieta) ; i_tmp -= w->temp_step ; } ; g_object_unref(gc) ; } ;
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P A N G O I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPANGOImage() reads an image in the Pango Markup Language Format. % % The format of the ReadPANGOImage method is: % % Image *ReadPANGOImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadPANGOImage(const ImageInfo *image_info, ExceptionInfo *exception) { cairo_font_options_t *font_options; cairo_surface_t *surface; char *caption, *property; cairo_t *cairo_image; const char *option; DrawInfo *draw_info; Image *image; MagickBooleanType status; PangoAlignment align; PangoContext *context; PangoFontMap *fontmap; PangoGravity gravity; PangoLayout *layout; PangoRectangle extent; PixelInfo fill_color; RectangleInfo page; register unsigned char *p; size_t stride; ssize_t y; unsigned char *pixels; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info,exception); (void) ResetImagePage(image,"0x0+0+0"); /* Format caption. */ option=GetImageArtifact(image,"filename"); if (option == (const char *) NULL) property=InterpretImageProperties(image_info,image,image_info->filename, exception); else if (LocaleNCompare(option,"pango:",6) == 0) property=InterpretImageProperties(image_info,image,option+6,exception); else property=InterpretImageProperties(image_info,image,option,exception); (void) SetImageProperty(image,"caption",property,exception); property=DestroyString(property); caption=ConstantString(GetImageProperty(image,"caption",exception)); /* Get context. */ fontmap=pango_cairo_font_map_new(); pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), image->resolution.x == 0.0 ? 90.0 : image->resolution.x); font_options=cairo_font_options_create(); option=GetImageArtifact(image,"pango:hinting"); if (option != (const char *) NULL) { if (LocaleCompare(option,"none") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE); if (LocaleCompare(option,"full") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL); } context=pango_font_map_create_context(fontmap); pango_cairo_context_set_font_options(context,font_options); cairo_font_options_destroy(font_options); option=GetImageArtifact(image,"pango:language"); if (option != (const char *) NULL) pango_context_set_language(context,pango_language_from_string(option)); draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); pango_context_set_base_dir(context,draw_info->direction == RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); switch (draw_info->gravity) { case NorthGravity: { gravity=PANGO_GRAVITY_NORTH; break; } case NorthWestGravity: case WestGravity: case SouthWestGravity: { gravity=PANGO_GRAVITY_WEST; break; } case NorthEastGravity: case EastGravity: case SouthEastGravity: { gravity=PANGO_GRAVITY_EAST; break; } case SouthGravity: { gravity=PANGO_GRAVITY_SOUTH; break; } default: { gravity=PANGO_GRAVITY_AUTO; break; } } pango_context_set_base_gravity(context,gravity); option=GetImageArtifact(image,"pango:gravity-hint"); if (option != (const char *) NULL) { if (LocaleCompare(option,"line") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE); if (LocaleCompare(option,"natural") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL); if (LocaleCompare(option,"strong") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG); } /* Configure layout. */ layout=pango_layout_new(context); option=GetImageArtifact(image,"pango:auto-dir"); if (option != (const char *) NULL) pango_layout_set_auto_dir(layout,1); option=GetImageArtifact(image,"pango:ellipsize"); if (option != (const char *) NULL) { if (LocaleCompare(option,"end") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END); if (LocaleCompare(option,"middle") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE); if (LocaleCompare(option,"none") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE); if (LocaleCompare(option,"start") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START); } option=GetImageArtifact(image,"pango:justify"); if (IfMagickTrue(IsStringTrue(option))) pango_layout_set_justify(layout,1); option=GetImageArtifact(image,"pango:single-paragraph"); if (IfMagickTrue(IsStringTrue(option))) pango_layout_set_single_paragraph_mode(layout,1); option=GetImageArtifact(image,"pango:wrap"); if (option != (const char *) NULL) { if (LocaleCompare(option,"char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_CHAR); if (LocaleCompare(option,"word") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD); if (LocaleCompare(option,"word-char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR); } option=GetImageArtifact(image,"pango:indent"); if (option != (const char *) NULL) pango_layout_set_indent(layout,(int) ((StringToLong(option)* (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)*PANGO_SCALE+36)/ 90.0+0.5)); switch (draw_info->align) { case CenterAlign: align=PANGO_ALIGN_CENTER; break; case RightAlign: align=PANGO_ALIGN_RIGHT; break; case LeftAlign: align=PANGO_ALIGN_LEFT; break; default: { if (draw_info->gravity == CenterGravity) { align=PANGO_ALIGN_CENTER; break; } align=PANGO_ALIGN_LEFT; break; } } if ((align != PANGO_ALIGN_CENTER) && (draw_info->direction == RightToLeftDirection)) align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align); pango_layout_set_alignment(layout,align); if (draw_info->font != (char *) NULL) { PangoFontDescription *description; /* Set font. */ description=pango_font_description_from_string(draw_info->font); pango_font_description_set_size(description,(int) (PANGO_SCALE* draw_info->pointsize+0.5)); pango_layout_set_font_description(layout,description); pango_font_description_free(description); } option=GetImageArtifact(image,"pango:markup"); if ((option != (const char *) NULL) && (IsStringTrue(option) == MagickFalse)) pango_layout_set_text(layout,caption,-1); else { GError *error; error=(GError *) NULL; if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0) (void) ThrowMagickException(exception,GetMagickModule(),CoderError, error->message,"`%s'",image_info->filename); pango_layout_set_markup(layout,caption,-1); } pango_layout_context_changed(layout); page.x=0; page.y=0; if (image_info->page != (char *) NULL) (void) ParseAbsoluteGeometry(image_info->page,&page); if (image->columns == 0) { pango_layout_get_extents(layout,NULL,&extent); image->columns=(extent.x+extent.width+PANGO_SCALE/2)/PANGO_SCALE+2*page.x; } else { image->columns-=2*page.x; pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns* (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)+45.0)/90.0+ 0.5)); } if (image->rows == 0) { pango_layout_get_extents(layout,NULL,&extent); image->rows=(extent.y+extent.height+PANGO_SCALE/2)/PANGO_SCALE+2*page.y; } else { image->rows-=2*page.y; pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows* (image->resolution.y == 0.0 ? 90.0 : image->resolution.y)+45.0)/90.0+ 0.5)); } /* Render markup. */ stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, image->columns); pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) { draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32, image->columns,image->rows,stride); cairo_image=cairo_create(surface); cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR); cairo_paint(cairo_image); cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER); cairo_translate(cairo_image,page.x,page.y); pango_cairo_show_layout(cairo_image,layout); cairo_destroy(cairo_image); cairo_surface_destroy(surface); g_object_unref(layout); g_object_unref(fontmap); /* Convert surface to image. */ (void) SetImageBackgroundColor(image,exception); p=pixels; GetPixelInfo(image,&fill_color); for (y=0; y < (ssize_t) image->rows; y++) { register Quantum *q; register ssize_t x; q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { double gamma; fill_color.blue=(double) ScaleCharToQuantum(*p++); fill_color.green=(double) ScaleCharToQuantum(*p++); fill_color.red=(double) ScaleCharToQuantum(*p++); fill_color.alpha=(double) ScaleCharToQuantum(*p++); /* Disassociate alpha. */ gamma=1.0-QuantumScale*fill_color.alpha; gamma=PerceptibleReciprocal(gamma); fill_color.blue*=gamma; fill_color.green*=gamma; fill_color.red*=gamma; CompositePixelOver(image,&fill_color,fill_color.alpha,q,(double) GetPixelAlpha(image,q),q); q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } /* Relinquish resources. */ pixels=(unsigned char *) RelinquishMagickMemory(pixels); draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); return(GetFirstImageInList(image)); }
static void on_context_changed(G_GNUC_UNUSED JoyStyle *theme, PangoLayout *layout) { pango_layout_context_changed(layout); }
static Image *ReadCAPTIONImage(const ImageInfo *image_info, ExceptionInfo *exception) { char *caption, *property; const char *option; DrawInfo *draw_info; FT_Bitmap *canvas; Image *image; PangoAlignment align; PangoContext *context; PangoFontDescription *description; PangoFontMap *fontmap; PangoGravity gravity; PangoLayout *layout; PangoRectangle extent; PixelPacket fill_color; RectangleInfo page; register PixelPacket *q; register unsigned char *p; ssize_t y; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); (void) ResetImagePage(image,"0x0+0+0"); /* Get context. */ fontmap=(PangoFontMap *) pango_ft2_font_map_new(); pango_ft2_font_map_set_resolution((PangoFT2FontMap *) fontmap, image->x_resolution,image->y_resolution); option=GetImageOption(image_info,"caption:hinting"); pango_ft2_font_map_set_default_substitute((PangoFT2FontMap *) fontmap, PangoSubstitute,(char *) option,NULL); context=pango_font_map_create_context(fontmap); option=GetImageOption(image_info,"caption:language"); if (option != (const char *) NULL) pango_context_set_language(context,pango_language_from_string(option)); draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); pango_context_set_base_dir(context,draw_info->direction == RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); switch (draw_info->gravity) { case NorthGravity: gravity=PANGO_GRAVITY_NORTH; break; case WestGravity: gravity=PANGO_GRAVITY_WEST; break; case EastGravity: gravity=PANGO_GRAVITY_EAST; break; case SouthGravity: gravity=PANGO_GRAVITY_SOUTH; break; default: gravity=PANGO_GRAVITY_AUTO; break; } pango_context_set_base_gravity(context,gravity); option=GetImageOption(image_info,"caption:gravity-hint"); if (option != (const char *) NULL) { if (LocaleCompare(option,"line") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE); if (LocaleCompare(option,"natural") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL); if (LocaleCompare(option,"strong") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG); } /* Configure layout. */ layout=pango_layout_new(context); option=GetImageOption(image_info,"caption:auto-dir"); if (option != (const char *) NULL) pango_layout_set_auto_dir(layout,1); option=GetImageOption(image_info,"caption:ellipsize"); if (option != (const char *) NULL) { if (LocaleCompare(option,"end") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END); if (LocaleCompare(option,"middle") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE); if (LocaleCompare(option,"none") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE); if (LocaleCompare(option,"start") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START); } option=GetImageOption(image_info,"caption:justify"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_justify(layout,1); option=GetImageOption(image_info,"caption:single-paragraph"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_single_paragraph_mode(layout,1); option=GetImageOption(image_info,"caption:wrap"); if (option != (const char *) NULL) { if (LocaleCompare(option,"char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_CHAR); if (LocaleCompare(option,"word") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD); if (LocaleCompare(option,"word-char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR); } option=GetImageOption(image_info,"caption:indent"); if (option != (const char *) NULL) pango_layout_set_indent(layout,(StringToLong(option)*image->x_resolution* PANGO_SCALE+36)/72); switch (draw_info->align) { case CenterAlign: align=PANGO_ALIGN_CENTER; break; case RightAlign: align=PANGO_ALIGN_RIGHT; break; case LeftAlign: default: align=PANGO_ALIGN_LEFT; break; } if ((align != PANGO_ALIGN_CENTER) && (draw_info->direction == RightToLeftDirection)) align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align); pango_layout_set_alignment(layout,align); description=pango_font_description_from_string(draw_info->font == (char *) NULL ? "helvetica" : draw_info->font); pango_font_description_set_size(description,PANGO_SCALE*draw_info->pointsize); pango_layout_set_font_description(layout,description); pango_font_description_free(description); property=InterpretImageProperties(image_info,image,image_info->filename); (void) SetImageProperty(image,"caption",property); property=DestroyString(property); caption=ConstantString(GetImageProperty(image,"caption")); /* Render caption. */ option=GetImageOption(image_info,"caption:markup"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_markup(layout,caption,-1); else pango_layout_set_text(layout,caption,-1); pango_layout_context_changed(layout); page.x=0; page.y=0; if (image_info->page != (char *) NULL) (void) ParseAbsoluteGeometry(image_info->page,&page); if (image->columns == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->columns=extent.x+extent.width; } else { image->columns-=2*page.x; pango_layout_set_width(layout,(PANGO_SCALE*image->columns* image->x_resolution+36.0)/72.0); } if (image->rows == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->rows=extent.y+extent.height; } else { image->rows-=2*page.y; pango_layout_set_height(layout,(PANGO_SCALE*image->rows* image->y_resolution+36.0)/72.0); } /* Create canvas. */ canvas=(FT_Bitmap *) AcquireMagickMemory(sizeof(*canvas)); if (canvas == (FT_Bitmap *) NULL) { draw_info=DestroyDrawInfo(draw_info); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } canvas->width=image->columns; canvas->pitch=(canvas->width+3) & ~3; canvas->rows=image->rows; canvas->buffer=(unsigned char *) AcquireQuantumMemory(canvas->pitch, canvas->rows*sizeof(*canvas->buffer)); if (canvas->buffer == (unsigned char *) NULL) { draw_info=DestroyDrawInfo(draw_info); canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } canvas->num_grays=256; canvas->pixel_mode=ft_pixel_mode_grays; ResetMagickMemory(canvas->buffer,0x00,canvas->pitch*canvas->rows); pango_ft2_render_layout(canvas,layout,0,0); /* Convert caption to image. */ image->columns+=2*page.x; image->rows+=2*page.y; if (SetImageBackgroundColor(image) == MagickFalse) { draw_info=DestroyDrawInfo(draw_info); canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer); canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas); caption=DestroyString(caption); image=DestroyImageList(image); return((Image *) NULL); } p=canvas->buffer; for (y=page.y; y < (ssize_t) (image->rows-page.y); y++) { register ssize_t x; q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; q+=page.x; for (x=page.x; x < (ssize_t) (image->columns-page.x); x++) { MagickRealType fill_opacity; (void) GetFillColor(draw_info,x,y,&fill_color); fill_opacity=QuantumRange-(*p)/canvas->num_grays*(QuantumRange- fill_color.opacity); if (draw_info->text_antialias == MagickFalse) fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0; MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q); p++; q++; } for ( ; x < (ssize_t) ((canvas->width+3) & ~3); x++) p++; } /* Relinquish resources. */ draw_info=DestroyDrawInfo(draw_info); canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer); canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas); caption=DestroyString(caption); return(GetFirstImageInList(image)); }
/* Redraw the vertical ruler */ static gboolean histo_expose_vertical_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) { histoDrawing_t *drawing = (histoDrawing_t*)user_data; HistoControlFlowData *histo_cfv = drawing->histo_control_flow_data; gchar text[255]; PangoContext *context; PangoLayout *layout; PangoFontDescription *FontDesc; PangoRectangle ink_rect; gint global_height=0; GdkColor foreground = { 0, 0, 0, 0 }; GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; GdkColor red ={ 0, 0xFFFF, 0x1E00, 0x1000 }; //GdkColor magneta ={ 0, 0x8900, 0x0000, 0x8400 }; g_debug("vertical ruler expose event"); gdk_draw_rectangle (drawing->vertical_ruler->window, drawing->vertical_ruler->style->white_gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_butt, padding_width-1/*event->area.width-1*/,event->area.y, padding_width-1/*event->area.width-1*/,event->area.y + event->area.height); snprintf(text, 255, "%.1f", (float)histo_cfv->max_height); layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); context = pango_layout_get_context(layout); FontDesc = pango_context_get_font_description(context); pango_font_description_set_size(FontDesc, 6*PANGO_SCALE); pango_layout_context_changed(layout); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, 1, layout, &foreground, &background); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_round, drawing->vertical_ruler-> allocation.width-1, 1, drawing->vertical_ruler-> allocation.width-7, 1); snprintf(text, 255, "%d", 0); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; if(global_height <= drawing->vertical_ruler->allocation.height) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, drawing->vertical_ruler->allocation.height - ink_rect.height-2, layout, &foreground, &background); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_butt, drawing->vertical_ruler-> allocation.width-1, drawing->vertical_ruler->allocation.height-1, drawing->vertical_ruler-> allocation.width-7, drawing->vertical_ruler->allocation.height-1); } snprintf(text, 255, "%.1f",(float) histo_cfv->max_height/2.0); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; if(global_height <= drawing->vertical_ruler->allocation.height) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/2, layout, &foreground, &background); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_butt, drawing->vertical_ruler-> allocation.width-1, drawing->vertical_ruler-> allocation.height/2, drawing->vertical_ruler-> allocation.width-7, drawing->vertical_ruler->allocation.height/2); } //show number of events at current time: LttTime current_time = lttvwindow_get_current_time(histo_cfv->tab); TimeWindow time_window = lttvwindow_get_time_window(histo_cfv->tab); LttTime time_begin = time_window.start_time; LttTime time_width = time_window.time_width; LttTime time_end = ltt_time_add(time_begin, time_width); if((ltt_time_compare(current_time, time_begin) >= 0)&& (ltt_time_compare(current_time, time_end) <= 0)) { guint *events_at_currenttime; guint max_height=histo_cfv ->max_height; guint x; histo_convert_time_to_pixels( time_window, current_time, drawing->width, &x); // if(x_test<histo_cfv->number_of_process->len) { events_at_currenttime = &g_array_index(histo_cfv->number_of_process,guint,x); if((*events_at_currenttime) > max_height) { snprintf(text, 255, "OverFlow!"); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/5, layout, &red, &background); }else // if((*events_at_currenttime) <= max_height) { snprintf(text, 255, "%.1f", (float) *events_at_currenttime); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; if ((*events_at_currenttime) == 0) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)-2, layout, &red, &background); } else if ((*events_at_currenttime) == max_height) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, 1, layout, &red, &background); } /*else if ((*events_at_currenttime) == max_height/2) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/2, layout, &red, &background); }*/ else if ((*events_at_currenttime) > max_height/2) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/4, layout, &red, &background); } else{ gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, ((drawing->vertical_ruler->allocation.height - ink_rect.height)*3)/4, layout, &red, &background); } } } } g_object_unref(layout); return FALSE; }
int main(int argc, char *argv[]) { gdImagePtr im; char *text; FILE *fp; int w,h; int margin_x, margin_y; gdPangoContext *context; gdPangoColors default_colors; PangoContext *pangocontext; PangoMatrix rotated_matrix = PANGO_MATRIX_INIT; PangoLayout *layout; gdPangoInit(); default_colors.fg = gdTrueColorAlpha(0, 255, 255, 0); default_colors.bg = gdTrueColorAlpha(255, 255, 255, 0); default_colors.alpha = 0; /* text = readFile("russian.txt"); text = readFile("arabic.txt"); text = readFile("hebrew.txt"); text = readFile("german.txt"); text = readFile("english.txt"); text = readFile("japanese.txt"); */ text = readFile("english.txt"); context = gdPangoCreateContext(); gdPangoSetDpi(context, 96, 96); gdPangoSetMinimumSize(context, 800, 200); gdPangoSetDefaultColor(context, &default_colors); gdPangoSetMarkup(context, text, -1); free(text); pangocontext = gdPangoGetPangoContext(context); layout = gdPangoGetPangoLayout(context); pango_context_set_base_dir(pangocontext, PANGO_DIRECTION_LTR); w = gdPangoGetLayoutWidth(context); h = gdPangoGetLayoutHeight(context); margin_x = 0; margin_y = 0; im = gdImageCreateTrueColor(800, 800); gdPangoRenderTo(context, im, margin_x, margin_y); fp = fopen("c.png", "wb"); gdImagePng(im, fp); fclose(fp); gdImageDestroy(im); context->angle = -30; if (context->angle != 0.0) { pango_matrix_rotate (&rotated_matrix, context->angle); pango_context_set_matrix(pangocontext, &rotated_matrix); pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); pango_layout_context_changed (layout); context->matrix = &rotated_matrix; } /* Render to a new image, sized for a rotated text */ im = gdPangoCreateSurfaceDraw(context); fp = fopen("d.png", "wb"); gdImagePng(im, fp); fclose(fp); gdPangoFreeContext(context); gdImageDestroy(im); return 0; }
static gboolean do_tests (CallbackData *data) { PangoFontDescription *fd; static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff }; PangoAttrList *attr_list, *attr_list_copy; PangoAttribute *attr; /* TEST 1: change the text */ clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 0"); pango_layout_set_text (data->test_layout, "Counter 0", -1); g_assert (check_result (data, "Change text", TRUE) == FALSE); /* TEST 2: change a single character */ clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 1"); pango_layout_set_text (data->test_layout, "Counter 1", -1); g_assert (check_result (data, "Change a single character", TRUE) == FALSE); /* TEST 3: move the label */ clutter_actor_set_position (data->label, 10, 0); g_assert (check_result (data, "Move the label", FALSE) == FALSE); /* TEST 4: change the font */ clutter_text_set_font_name (CLUTTER_TEXT (data->label), "Serif 15"); fd = pango_font_description_from_string ("Serif 15"); pango_layout_set_font_description (data->test_layout, fd); pango_font_description_free (fd); g_assert (check_result (data, "Change the font", TRUE) == FALSE); /* TEST 5: change the color */ clutter_text_set_color (CLUTTER_TEXT (data->label), &red); g_assert (check_result (data, "Change the color", FALSE) == FALSE); /* TEST 6: change the attributes */ attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); attr->start_index = 0; attr->end_index = 2; attr_list = pango_attr_list_new (); pango_attr_list_insert (attr_list, attr); attr_list_copy = pango_attr_list_copy (attr_list); clutter_text_set_attributes (CLUTTER_TEXT (data->label), attr_list); pango_layout_set_attributes (data->test_layout, attr_list_copy); pango_attr_list_unref (attr_list_copy); pango_attr_list_unref (attr_list); g_assert (check_result (data, "Change the attributes", TRUE) == FALSE); /* TEST 7: change the text again */ clutter_text_set_attributes (CLUTTER_TEXT (data->label), NULL); clutter_text_set_text (CLUTTER_TEXT (data->label), long_text); pango_layout_set_attributes (data->test_layout, NULL); pango_layout_set_text (data->test_layout, long_text, -1); g_assert (check_result (data, "Change the text again", TRUE) == FALSE); /* TEST 8: enable markup */ clutter_text_set_use_markup (CLUTTER_TEXT (data->label), TRUE); pango_layout_set_markup (data->test_layout, long_text, -1); g_assert (check_result (data, "Enable markup", TRUE) == FALSE); /* This part can't be a test because Clutter won't restrict the width if wrapping and ellipsizing is disabled so the extents will be different, but we still want to do it for the later tests */ clutter_actor_set_width (data->label, 200); pango_layout_set_width (data->test_layout, 200 * PANGO_SCALE); /* Force a redraw so that changing the width won't affect the results */ force_redraw (data); /* TEST 9: enable ellipsize */ clutter_text_set_ellipsize (CLUTTER_TEXT (data->label), PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_END); g_assert (check_result (data, "Enable ellipsize", TRUE) == FALSE); clutter_text_set_ellipsize (CLUTTER_TEXT (data->label), PANGO_ELLIPSIZE_NONE); pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_NONE); force_redraw (data); /* TEST 10: enable line wrap */ clutter_text_set_line_wrap (CLUTTER_TEXT (data->label), TRUE); pango_layout_set_wrap (data->test_layout, PANGO_WRAP_WORD); g_assert (check_result (data, "Enable line wrap", TRUE) == FALSE); /* TEST 11: change wrap mode * FIXME - broken */ clutter_text_set_line_wrap_mode (CLUTTER_TEXT (data->label), PANGO_WRAP_CHAR); pango_layout_set_wrap (data->test_layout, PANGO_WRAP_CHAR); g_assert (check_result (data, "Change wrap mode", TRUE) == FALSE); /* TEST 12: enable justify */ clutter_text_set_justify (CLUTTER_TEXT (data->label), TRUE); pango_layout_set_justify (data->test_layout, TRUE); /* Pango appears to have a bug which means that you can't change the justification after setting the text but this fixes it. See http://bugzilla.gnome.org/show_bug.cgi?id=551865 */ pango_layout_context_changed (data->test_layout); g_assert (check_result (data, "Enable justify", TRUE) == FALSE); /* TEST 13: change alignment */ clutter_text_set_line_alignment (CLUTTER_TEXT (data->label), PANGO_ALIGN_RIGHT); pango_layout_set_alignment (data->test_layout, PANGO_ALIGN_RIGHT); g_assert (check_result (data, "Change alignment", TRUE) == FALSE); clutter_main_quit (); return FALSE; }