static cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_glyph_t *glyphs = xmalloc (NUM_GLYPHS * sizeof (cairo_glyph_t)); cairo_scaled_font_t *scaled_font; const char *characters[] = { /* try to exercise different widths of index */ "m", /* Latin letter m, index=0x50 */ "μ", /* Greek letter mu, index=0x349 */ NULL, }, **utf8; int i, j; cairo_status_t status; /* Paint white background. */ cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, TEXT_SIZE); scaled_font = cairo_get_scaled_font (cr); for (utf8 = characters; *utf8 != NULL; utf8++) { status = get_glyph (ctx, scaled_font, *utf8, &glyphs[0]); if (status) goto BAIL; if (glyphs[0].index) { glyphs[0].x = 1.0; glyphs[0].y = height - 1; for (i=1; i < NUM_GLYPHS; i++) glyphs[i] = glyphs[0]; cairo_show_glyphs (cr, glyphs, NUM_GLYPHS); } } /* we can pack ~21k 1-byte glyphs into a single XRenderCompositeGlyphs8 */ status = get_glyph (ctx, scaled_font, "m", &glyphs[0]); if (status) goto BAIL; for (i=1; i < 21500; i++) glyphs[i] = glyphs[0]; /* so check expanding the current 1-byte request for 2-byte glyphs */ status = get_glyph (ctx, scaled_font, "μ", &glyphs[i]); if (status) goto BAIL; for (j=i+1; j < NUM_GLYPHS; j++) glyphs[j] = glyphs[i]; cairo_show_glyphs (cr, glyphs, NUM_GLYPHS); BAIL: free(glyphs); return status; }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_glyph_t glyphs[NUM_GLYPHS]; int i; /* Initialize our giant array of glyphs. */ for (i=0; i < NUM_GLYPHS; i++) { glyphs[i].index = GLYPH_INDEX; glyphs[i].x = 1.0; glyphs[i].y = height - 1; } /* Paint white background. */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); cairo_select_font_face (cr, "Bitstream Vera Sans Mono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, TEXT_SIZE); cairo_show_glyphs (cr, glyphs, NUM_GLYPHS); return CAIRO_TEST_SUCCESS; }
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { GuiLock __; int ascent = font.GetAscent(); double sina = 0; double cosa = 1; if(angle) Draw::SinCos(angle, sina, cosa); int xpos = 0; Buffer<cairo_glyph_t> gs(n); for(int i = 0; i < n; i++) { cairo_glyph_t& g = gs[i]; g.index = GetGlyphInfo(font, text[i]).glyphi; g.x = fround(x + cosa * xpos + sina * ascent); g.y = fround(y + cosa * ascent - sina * xpos); xpos += dx ? dx[i] : font[text[i]]; } static LRUCache<FontSysData, Tuple2<Font, int> > cache; FontDataSysMaker m; m.font = font; m.angle = angle; FontSysData& sf = cache.Get(m); cairo_set_scaled_font(cr, sf.scaled_font); SetColor(ink); cairo_show_glyphs(cr, gs, n); cache.Shrink(64); }
void Font::drawGlyphs(GraphicsContext* graphicsContext, const FontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* context = graphicsContext->platformContext(); // Set the text color to use for drawing. float red, green, blue, alpha; Color penColor = graphicsContext->pen().color(); penColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(context, red, green, blue, alpha); // Select the scaled font. font->setFont(context); GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from); float offset = point.x(); for (unsigned i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = point.y(); offset += glyphBuffer.advanceAt(from + i); } cairo_show_glyphs(context, glyphs, numGlyphs); }
void Font::drawGlyphs(GraphicsContext* graphicsContext, const FontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* context = graphicsContext->platformContext(); // Set the text color to use for drawing. float red, green, blue, alpha; Color penColor = graphicsContext->fillColor(); penColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(context, red, green, blue, alpha); // This was commented out as it made "some text invisible" but seems to work now. font->setFont(context); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*) glyphBuffer.glyphs(from); float offset = point.x(); for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = point.y(); offset += glyphBuffer.advanceAt(from + i); } cairo_show_glyphs(context, glyphs, numGlyphs); }
static void text_layout_draw(struct text_layout *layout, cairo_t *cr) { cairo_save(cr); cairo_set_scaled_font(cr, layout->font); cairo_show_glyphs(cr, layout->glyphs, layout->num_glyphs); cairo_restore(cr); }
static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs) { cairo_matrix_t originalTransform; float syntheticBoldOffset = font->syntheticBoldOffset(); if (syntheticBoldOffset) cairo_get_matrix(context, &originalTransform); cairo_set_scaled_font(context, font->platformData().scaledFont()); cairo_show_glyphs(context, glyphs, numGlyphs); if (syntheticBoldOffset) { cairo_translate(context, syntheticBoldOffset, 0); cairo_show_glyphs(context, glyphs, numGlyphs); } if (syntheticBoldOffset) cairo_set_matrix(context, &originalTransform); }
void cairo_context::show_glyph(unsigned long index, double x, double y) { cairo_glyph_t glyph; glyph.index = index; glyph.x = x; glyph.y = y; cairo_show_glyphs(cairo_.get(), &glyph, 1); check_object_status_and_throw_exception(*this); }
void cairo_context::show_glyph(unsigned long index, pixel_position const &pos) { cairo_glyph_t glyph; glyph.index = index; glyph.x = pos.x; glyph.y = pos.y; cairo_show_glyphs(cairo_.get(), &glyph, 1); check_object_status_and_throw_exception(*this); }
static VALUE cr_show_glyphs (VALUE self, VALUE rb_glyphs) { int count; cairo_glyph_t *glyphs; RB_CAIRO__GLYPHS_TO_ARRAY (rb_glyphs, glyphs, count); cairo_show_glyphs (_SELF, glyphs, count); cr_check_status (_SELF); return self; }
CAMLprim value ml_cairo_show_glyphs (value v_cr, value v_glyphs) { int num_glyphs; cairo_glyph_t *c_glyphs; c_glyphs = ml_convert_cairo_glypth_in (v_glyphs, &num_glyphs); cairo_show_glyphs (cairo_t_val (v_cr), c_glyphs, num_glyphs); caml_stat_free (c_glyphs); check_cairo_status (v_cr); return Val_unit; }
static int cr_show_glyphs (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_glyph_t *glyphs; int num_glyphs; from_lua_glyph_array(L, &glyphs, &num_glyphs, 2); cairo_show_glyphs(*obj, glyphs, num_glyphs); if (glyphs) GLYPHS_FREE(glyphs); return 0; }
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs (JNIEnv *env, jobject obj, jintArray java_codes, jfloatArray java_posns) { struct graphics2d *gr = NULL; cairo_glyph_t *glyphs = NULL; jfloat *native_posns = NULL; jint *native_codes = NULL; jint i; jint ncodes, nposns; gdk_threads_enter(); if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; } gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); g_assert (gr != NULL); native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL); native_posns = (*env)->GetFloatArrayElements (env, java_posns, NULL); g_assert (native_codes != NULL); g_assert (native_posns != NULL); ncodes = (*env)->GetArrayLength (env, java_codes); nposns = (*env)->GetArrayLength (env, java_posns); g_assert (2 * ncodes == nposns); if (gr->debug) printf ("cairo_show_glyphs (%d glyphs)\n", ncodes); glyphs = malloc (sizeof(cairo_glyph_t) * ncodes); g_assert (glyphs); for (i = 0; i < ncodes; ++i) { glyphs[i].index = native_codes[i]; glyphs[i].x = (double) native_posns[2*i]; glyphs[i].y = (double) native_posns[2*i + 1]; if (gr->debug) printf ("cairo_show_glyphs (glyph %d (code %d) : %f,%f)\n", i, glyphs[i].index, glyphs[i].x, glyphs[i].y); } (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0); (*env)->ReleaseFloatArrayElements (env, java_posns, native_posns, 0); begin_drawing_operation (gr); cairo_show_glyphs (gr->cr, glyphs, ncodes); end_drawing_operation (gr); free(glyphs); gdk_threads_leave(); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_font_options_t *font_options; cairo_scaled_font_t *scaled_font; FT_Face face; FT_ULong charcode; FT_UInt idx; int i = 0; cairo_glyph_t glyphs[NUM_GLYPHS]; /* paint white so we don't need separate ref images for * RGB24 and ARGB32 */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_paint (cr); cairo_select_font_face (cr, "Bitstream Vera Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, TEXT_SIZE); font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); cairo_set_font_options (cr, font_options); cairo_font_options_destroy (font_options); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); scaled_font = cairo_get_scaled_font (cr); face = cairo_ft_scaled_font_lock_face (scaled_font); { charcode = FT_Get_First_Char(face, &idx); while (idx && (i < NUM_GLYPHS)) { glyphs[i] = (cairo_glyph_t) {idx, PAD + GRID_SIZE * (i/GRID_ROWS), PAD + TEXT_SIZE + GRID_SIZE * (i%GRID_ROWS)}; i++; charcode = FT_Get_Next_Char(face, charcode, &idx); } } cairo_ft_scaled_font_unlock_face (scaled_font); cairo_show_glyphs(cr, glyphs, i); return CAIRO_TEST_SUCCESS; }
ilA_img *ilG_gui_textlayout_render(ilG_gui_textlayout *self, float col[4], enum ilG_gui_textoptions opts) { (void)opts; unsigned w = 0, h = 0; unsigned x = 0, y = 0; int bx = 0, by = 0; int scale = 64; unsigned i; self->cairo_ft_face = cairo_ft_font_face_create_for_ft_face(self->ft_face, 0); self->hb_ft_face = hb_ft_face_create(self->ft_face, NULL); x *= scale; y *= scale; self->cairo_glyphs = calloc(self->glyph_count, sizeof(cairo_glyph_t)); for (i = 0; i < self->glyph_count; i++) { self->cairo_glyphs[i].index = self->glyph_info[i].codepoint; self->cairo_glyphs[i].x = (x + self->glyph_pos[i].x_offset)/scale; self->cairo_glyphs[i].y = (y + self->glyph_pos[i].y_offset)/scale; x += self->glyph_pos[i].x_advance; y += self->glyph_pos[i].y_advance; } ilG_gui_textlayout_getExtents(self, &w, &h, &bx, &by, NULL, NULL); self->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); self->cr = cairo_create(self->surface); cairo_translate(self->cr, -bx, 1-by); cairo_set_source_rgba(self->cr, col[0], col[1], col[2], col[3]); cairo_set_font_face(self->cr, self->cairo_ft_face); cairo_set_font_size(self->cr, self->pt); cairo_show_glyphs(self->cr, self->cairo_glyphs, self->glyph_count); cairo_surface_flush(self->surface); ilA_img *preswizzle = ilA_img_fromdata(cairo_image_surface_get_data(self->surface), w, h, 8, ILA_IMG_RGBA); /* R G B A | 0x * B 0 0 1 0 | 2 * G 0 1 0 0 | 4 * R 1 0 0 0 | 8 * A 0 0 0 1 | 1 */ ilA_img *img = ilA_img_bgra_to_rgba(preswizzle);//ilA_img_swizzle(preswizzle, 0x2481); ilA_img_free(preswizzle); return img; }
/* adapted from gnome-utils:font-viewer/font-view.c * * Copyright (C) 2002-2003 James Henstridge <*****@*****.**> * Copyright (C) 2010 Cosimo Cecchi <*****@*****.**> * * License: GPLv2+ */ static void draw_string (SushiFontWidget *self, cairo_t *cr, GtkBorder padding, const gchar *text, gint *pos_y) { cairo_font_extents_t font_extents; cairo_text_extents_t extents; cairo_glyph_t *glyphs; GtkTextDirection text_dir; gint pos_x; gint num_glyphs; gint i; text_dir = gtk_widget_get_direction (GTK_WIDGET (self)); text_to_glyphs (cr, text, &glyphs, &num_glyphs); cairo_font_extents (cr, &font_extents); cairo_glyph_extents (cr, glyphs, num_glyphs, &extents); if (pos_y != NULL) *pos_y += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING / 2; if (text_dir == GTK_TEXT_DIR_LTR) pos_x = padding.left; else { pos_x = gtk_widget_get_allocated_width (GTK_WIDGET (self)) - extents.x_advance - padding.right; } for (i = 0; i < num_glyphs; i++) { glyphs[i].x += pos_x; glyphs[i].y += *pos_y; } cairo_move_to (cr, pos_x, *pos_y); cairo_show_glyphs (cr, glyphs, num_glyphs); g_free (glyphs); *pos_y += LINE_SPACING / 2; }
void dv_draw_text(cairo_t *cr) { cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 13); const int n_glyphs = 20 * 35; cairo_glyph_t glyphs[n_glyphs]; gint i = 0; gint x, y; for (y=0; y<20; y++) { for (x=0; x<35; x++) { glyphs[i] = (cairo_glyph_t) {i, x*15 + 20, y*18 + 20}; i++; } } cairo_show_glyphs(cr, glyphs, n_glyphs); }
Path CairoGlyphToPathTranslator::path() { Path path; path.ensurePlatformPath(); cairo_glyph_t cairoGlyph; cairoGlyph.index = m_glyphBuffer.glyphAt(m_index); cairo_set_scaled_font(path.platformPath()->context(), m_fontData->platformData().scaledFont()); cairo_glyph_path(path.platformPath()->context(), &cairoGlyph, 1); float syntheticBoldOffset = m_fontData->syntheticBoldOffset(); if (syntheticBoldOffset) { cairo_translate(path.platformPath()->context(), syntheticBoldOffset, 0); cairo_show_glyphs(path.platformPath()->context(), &cairoGlyph, 1); } path.transform(m_translation); return path; }
static PyObject * pycairo_show_glyphs (PycairoContext *o, PyObject *args) { int num_glyphs = -1; cairo_glyph_t *glyphs; PyObject *py_object; if (!PyArg_ParseTuple (args, "O|i:Context.show_glyphs", &py_object, &num_glyphs)) return NULL; glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); if (glyphs == NULL) return NULL; Py_BEGIN_ALLOW_THREADS; cairo_show_glyphs (o->ctx, glyphs, num_glyphs); Py_END_ALLOW_THREADS; PyMem_Free (glyphs); RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); Py_RETURN_NONE; }
static cairo_status_t test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *extents) { cairo_glyph_t cairo_glyph; cairo_glyph.index = glyph; cairo_glyph.x = 0; cairo_glyph.y = 0; cairo_set_font_face (cr, cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &fallback_font_key)); cairo_show_glyphs (cr, &cairo_glyph, 1); cairo_glyph_extents (cr, &cairo_glyph, 1, extents); return CAIRO_STATUS_SUCCESS; }
void CairoRenderer::RenderString(const String *pString) { int i, n; int *glyphs; cairo_glyph_t *cg; n = pString->GetLength(); glyphs = new int[n]; n = m_pFontData->CharCodesToGlyphs(pString->GetValue(), n, glyphs); cg = new cairo_glyph_t[n]; for (i = 0; i < n; ++i) { cg[i].index = glyphs[i]; cg[i].x = 0; cg[i].y = 0; } cairo_show_glyphs(m_pCairo, cg, n); delete[] cg; delete[] glyphs; }
static void glyph_array_show (glyph_array_t *glyphs, cairo_t *cr) { cairo_show_glyphs (cr, glyphs->glyph_list, glyphs->num_glyphs); }
static cairo_perf_ticks_t do_glyphs (cairo_t *cr, int width, int height, int loops) { const char text[] = "the jay, pig, fox, zebra and my wolves quack"; cairo_scaled_font_t *scaled_font; cairo_glyph_t *glyphs = NULL, *glyphs_copy; cairo_text_extents_t extents; cairo_status_t status; double x, y; int num_glyphs, n; cairo_set_font_size (cr, 9); scaled_font = cairo_get_scaled_font (cr); status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., text, -1, &glyphs, &num_glyphs, NULL, NULL, NULL); if (status) return 0; glyphs_copy = cairo_glyph_allocate (num_glyphs); if (glyphs_copy == NULL) { cairo_glyph_free (glyphs); return 0; } cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, &extents); y = 0; cairo_perf_timer_start (); while (loops--) { do { x = 0; do { for (n = 0; n < num_glyphs; n++) { glyphs_copy[n] = glyphs[n]; glyphs_copy[n].x += x; glyphs_copy[n].y += y; } cairo_show_glyphs (cr, glyphs_copy, num_glyphs); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) goto out; x += extents.width; } while (x < width); y += extents.height; } while (y < height); } out: cairo_perf_timer_stop (); cairo_glyph_free (glyphs); cairo_glyph_free (glyphs_copy); return cairo_perf_timer_elapsed (); }
/** * Handle console expose events */ void Console_expose(Console* self, cairo_t* context) { /* a pretty background */ cairo_save(context); cairo_set_source_rgb(context, 1.0, 1.0, 1.0); cairo_translate(context, self->width / 2, self->height / 2); double t = pi / 4; for (double n = 0; n < pi * 2; n += t) { cairo_rectangle(context, 20, 20, 140, 40); cairo_fill(context); cairo_rotate(context, t); } cairo_restore(context); /* set console:width and console:height */ char buf[256]; sprintf(buf, "(set 'console:width %d)", (int)self->width); Expression* e = Expression_parse_utf8(buf, null, &self->lithp->symbol_list); _gc_protect(e); Expression_eval(e, self->lithp->environment); _gc_unprotect(e); sprintf(buf, "(set 'console:height %d)", (int)self->height); e = Expression_parse_utf8(buf, null, &self->lithp->symbol_list); _gc_protect(e); Expression_eval(e, self->lithp->environment); _gc_unprotect(e); /* invoke callbacks inside lithp */ cairo_save(context); Expression* fn = Expression_intern("console:expose-event", &self->lithp->symbol_list); Expression* arg = _new_Expression(pointer); arg->car = (void*)context; _gc_protect(fn); _gc_protect(arg); Expression* callback = Expression_cons(fn, (Expression_cons(arg, nil_))); _gc_protect(callback); Expression_eval(callback, self->lithp->environment); _gc_unprotect(callback); _gc_unprotect(arg); _gc_unprotect(fn); cairo_restore(context); /* force lithp to garbage collect - TODO fix */ self->lithp->gc->free_list = _gc_collect(); /* select font */ cairo_set_font_face(context, cairo_ft_font_face_create_for_ft_face(*self->font_face, 0)); cairo_set_font_size(context, self->font_size); /* layout text */ Console_layout(self); /* render text */ cairo_set_source_rgb(context, 0, 0, 0); glyph_list* current = self->head; while (current) { cairo_show_glyphs(context, current->glyph, 1); current = current->next; } /* render cursor */ cairo_set_source_rgba(context, 0, 0, 1, 0.5); double x = 0; double y = 0; if (self->cursor) { x = self->cursor->glyph->x; // + self->font_extents->max_x_advance; y = self->cursor->glyph->y - self->font_extents->ascent; } cairo_rectangle(context, x, y, self->font_extents->max_x_advance, self->font_extents->height); cairo_fill(context); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_text_extents_t extents, nil_extents; cairo_font_extents_t font_extents, nil_font_extents; cairo_scaled_font_t *scaled_font; cairo_select_font_face (cr, "Bitstream Vera Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, 16); cairo_move_to (cr, 10, 25); cairo_show_text (cr, NULL); cairo_show_text (cr, ""); cairo_show_glyphs (cr, NULL, 0); cairo_show_glyphs (cr, (void*)8, 0); cairo_move_to (cr, 10, 55); cairo_text_path (cr, NULL); cairo_text_path (cr, ""); cairo_glyph_path (cr, (void*)8, 0); cairo_fill (cr); memset (&nil_extents, 0, sizeof (cairo_text_extents_t)); memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_text_extents (cr, "", &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_text_extents (cr, NULL, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_glyph_extents (cr, (void*)8, 0, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_glyph_extents(); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } scaled_font = cairo_get_scaled_font (cr); memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_scaled_font_text_extents (scaled_font, "", &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_scaled_font_text_extents (scaled_font, NULL, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_scaled_font_glyph_extents (scaled_font, (void*)8, 0, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_scaled_font_glyph_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } /* Lets also try font size 0 while here */ cairo_set_font_size (cr, 0); memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_text_extents (cr, "test", &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_text_extents(\"test\"); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&nil_font_extents, 0, sizeof (cairo_font_extents_t)); memset (&font_extents, 0xff, sizeof (cairo_font_extents_t)); cairo_font_extents (cr, &font_extents); if (! font_extents_equal (&font_extents, &nil_font_extents)) { cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n", font_extents.ascent, font_extents.descent, font_extents.height, font_extents.max_x_advance, font_extents.max_y_advance); return CAIRO_TEST_FAILURE; } scaled_font = cairo_get_scaled_font (cr); memset (&font_extents, 0xff, sizeof (cairo_font_extents_t)); cairo_scaled_font_extents (scaled_font, &font_extents); if (! font_extents_equal (&font_extents, &nil_font_extents)) { cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_scaled_font_extents(); extents (%g, %g, %g, %g, %g)\n", font_extents.ascent, font_extents.descent, font_extents.height, font_extents.max_x_advance, font_extents.max_y_advance); return CAIRO_TEST_FAILURE; } return CAIRO_TEST_SUCCESS; }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); font->setFont(cr); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = point.x(); for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = point.y(); offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Text shadow, inspired by FontMac IntSize shadowSize; int shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() == cTextFill && context->getShadow(shadowSize, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); cairo_translate(cr, shadowSize.width(), shadowSize.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { TransformationMatrix affine; cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); } if (context->textDrawingMode() & cTextStroke) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { TransformationMatrix affine; cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowSize, shadowBlur, shadowColor); cairo_restore(cr); }
/* * Paint a block of characters all in the same attribute. * You should have already determined that these characters have the * same attribute before calling this. */ static void vga_block_paint(VGAText *vga, cairo_t *cr, int col, int row, int chars) { int x, y; int i, ci; vga_charcell *cell; vga_charcell *video_buf; //printf("vga_block_paint(col=%d, row=%d, chars=%d)\n", col, row, chars); if (chars == 0) return; x = col * vga->pvt->font->width; y = row * vga->pvt->font->height; cairo_move_to(cr, x, y); if (vga->pvt->render_sec_buf) video_buf = vga->pvt->sec_buf; else video_buf = vga->pvt->video_buf; #if 1 /* Draw background rectangle */ gdk_cairo_set_source_color(cr, vga_palette_get_color(vga->pvt->pal, vga->pvt->bg)); cairo_rectangle(cr, x, y, vga->pvt->font->width * chars, vga->pvt->font->height); cairo_fill(cr); #endif /* Draw characters */ cairo_move_to(cr, x, y); gdk_cairo_set_source_color(cr, vga_palette_get_color(vga->pvt->pal, vga->pvt->fg)); /* Build up NULL-terminated line_buf string for cairo_show_text() */ ci = 0; for (i = 0; i < chars; i++) { cell = &(video_buf[row * 80 + col + i]); vga->pvt->glyphs[i].index = cell->c; vga->pvt->glyphs[i].x = x + (vga->pvt->font->width * i); vga->pvt->glyphs[i].y = y; #if 1 if (cell->c < 128) { vga->pvt->line_buf[ci++] = (cell->c == '\0' ? ' ' : cell->c); } else { /* * We have to encode our extended ASCII characters * into the Unicode PUA so that Cairo doesn't think * they are real UTF-8 bytes. Then, in the vgafont * user font, we translate PUA area glyphs back * into the regular extended ASCII glyphs */ /* IBM 8-bit extended ASCII, use Unicode PUA (U+E000) */ /* * Encoded in UTF-8 as: * 1110xxxx 10xxxxxx 10xxxxxx * ^^^ ^^^^ ^^^^^^ ^^^^^^ * | | | | * | \______|________| * | | * | Remaining bits concatenated to * | form Unicode code point value * \ * "3 bytes in sequence" * * So for U+E000 we use: * 11101110 100000xx 10xxxxxx */ vga->pvt->line_buf[ci++] = 0xee; vga->pvt->line_buf[ci++] = 0x80 | (cell->c >> 6); vga->pvt->line_buf[ci++] = 0x80 | (cell->c & 0x3f); //printf("extended char: 0x%02x\n", cell->c); } #endif } vga->pvt->line_buf[ci] = '\0'; //printf("%s\n", vga->pvt->line_buf); //cairo_show_text(cr, (const char *) vga->pvt->line_buf); cairo_show_glyphs(cr, vga->pvt->glyphs, chars); //printf("show_text(x,y=%d,%d col,row=%d,%d,fg=%d,bg=%d): %s\n", x, y, col, row, vga->pvt->fg, vga->pvt->bg, vga->pvt->line_buf); }
void ScreenPainter::drawGlyph(const GlyphLayout gl) { bool showControls = (m_item->doc()->guidesPrefs().showControls) && (gl.glyph == font().char2CMap(QChar(' ')) || gl.glyph >= ScFace::CONTROL_GLYPHS); #if CAIRO_HAS_FC_FONT if (m_painter->fillMode() == 1 && m_painter->maskMode() <= 0 && !showControls) { m_painter->save(); setupState(false); cairo_t* cr = m_painter->context(); double r, g, b; m_painter->brush().getRgbF(&r, &g, &b); cairo_set_source_rgba(cr, r, g, b, m_painter->brushOpacity()); m_painter->setRasterOp(m_painter->blendModeFill()); if (m_fontPath != font().fontFilePath() || m_faceIndex != font().faceIndex() || m_cairoFace == NULL) { m_fontPath = font().fontFilePath(); m_faceIndex = font().faceIndex(); // A very ugly hack as we can’t use the font().ftFace() because // Scribus liberally calls FT_Set_CharSize() with all sorts of // crazy values, breaking any subsequent call to the layout // painter. FIXME: drop the FontConfig dependency here once // Scribus font handling code is made sane! FcPattern *pattern = FcPatternBuild(NULL, FC_FILE, FcTypeString, QFile::encodeName(font().fontFilePath()).data(), FC_INDEX, FcTypeInteger, font().faceIndex(), NULL); m_cairoFace = cairo_ft_font_face_create_for_pattern(pattern); FcPatternDestroy(pattern); } cairo_set_font_face(cr, m_cairoFace); cairo_set_font_size(cr, fontSize()); cairo_scale(cr, gl.scaleH, gl.scaleV); cairo_glyph_t glyph = { gl.glyph, 0, 0 }; cairo_show_glyphs(cr, &glyph, 1); m_painter->restore(); return; } #endif m_painter->save(); setupState(false); bool fr = m_painter->fillRule(); m_painter->setFillRule(false); uint gid = gl.glyph; if (showControls) { bool stroke = false; if (gid >= ScFace::CONTROL_GLYPHS) gid -= ScFace::CONTROL_GLYPHS; else gid = 32; QTransform chma, chma4; FPointArray outline; if (gid == SpecialChars::TAB.unicode()) { outline = m_item->doc()->symTab.copy(); chma4.translate(gl.xadvance - fontSize() * gl.scaleH * 0.7, -fontSize() * gl.scaleV * 0.5); } else if (gid == SpecialChars::COLBREAK.unicode()) { outline = m_item->doc()->symNewCol.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.6); } else if (gid == SpecialChars::FRAMEBREAK.unicode()) { outline = m_item->doc()->symNewFrame.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.6); } else if (gid == SpecialChars::PARSEP.unicode()) { outline = m_item->doc()->symReturn.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.8); } else if (gid == SpecialChars::LINEBREAK.unicode()) { outline = m_item->doc()->symNewLine.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.4); } else if (gid == SpecialChars::NBSPACE.unicode() || gid == 32) { stroke = (gid == 32); outline = m_item->doc()->symNonBreak.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.4); } else if (gid == SpecialChars::NBHYPHEN.unicode()) { outline = font().glyphOutline(font().char2CMap(QChar('-')), fontSize()); chma4.translate(0, -fontSize() * gl.scaleV); } else if (gid == SpecialChars::SHYPHEN.unicode()) { outline.resize(0); outline.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6); stroke = true; } else if (gid == SpecialChars::OBJECT.unicode()) { //for showing marks entries as control chars outline.resize(0); outline.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6); stroke = true; } else // ??? { outline.resize(0); outline.addQuadPoint(0, -10, 0, -10, 0, -9, 0, -9); outline.addQuadPoint(0, -9, 0, -9, 1, -9, 1, -9); outline.addQuadPoint(1, -9, 1, -9, 1, -10, 1, -10); outline.addQuadPoint(1, -10, 1, -10, 0, -10, 0, -10); } chma.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0); outline.map(chma * chma4); m_painter->setupPolygon(&outline, true); QColor oldBrush = m_painter->brush(); // FIXME /* p->setBrush( (flags & ScLayout_SuppressSpace) ? Qt::green : PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor);*/ m_painter->setBrush(PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor); if (stroke) { QColor tmp = m_painter->pen(); m_painter->setStrokeMode(1); m_painter->setPen(m_painter->brush(), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); m_painter->setLineWidth(fontSize() * gl.scaleV / 20.0); m_painter->strokePath(); m_painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); } else { m_painter->setFillMode(1); m_painter->fillPath(); } m_painter->setBrush(oldBrush); } else { m_painter->translate(0, -(fontSize() * gl.scaleV)); double scaleH = gl.scaleH * fontSize() / 10.0; double scaleV = gl.scaleV * fontSize() / 10.0; m_painter->scale(scaleH, scaleV); FPointArray outline = font().glyphOutline(gid); m_painter->setupPolygon(&outline, true); if (outline.size() > 3) m_painter->fillPath(); } m_painter->setFillRule(fr); m_painter->restore(); }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); cairo_set_scaled_font(cr, font->platformData().scaledFont()); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = 0.0f; for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = 0.0f; offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Synthetic Oblique if(font->platformData().syntheticOblique()) { cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()}; cairo_transform(cr, &mat); } else { cairo_translate(cr, point.x(), point.y()); } // Text shadow, inspired by FontMac FloatSize shadowOffset; float shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() & cTextFill && context->getShadow(shadowOffset, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if ENABLE(FILTERS) cairo_text_extents_t extents; cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height)); IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); // Draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); GraphicsContext* shadowContext = shadowBuffer->context(); cairo_t* shadowCr = shadowContext->platformContext(); cairo_translate(shadowCr, radius, extents.height + radius); cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(shadowCr); cairo_translate(shadowCr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); cairo_restore(shadowCr); } cairo_translate(cr, 0.0, -extents.height); context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); #else cairo_translate(cr, shadowOffset.width(), shadowOffset.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } #endif cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { AffineTransform affine; cairo_pattern_t* pattern = context->fillPattern()->createPlatformPattern(affine); cairo_set_source(cr, pattern); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } cairo_pattern_destroy(pattern); } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } } // Prevent running into a long computation within cairo. If the stroke width is // twice the size of the width of the text we will not ask cairo to stroke // the text as even one single stroke would cover the full wdth of the text. // See https://bugs.webkit.org/show_bug.cgi?id=33759. if (context->textDrawingMode() & cTextStroke && context->strokeThickness() < 2 * offset) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { AffineTransform affine; cairo_pattern_t* pattern = context->strokePattern()->createPlatformPattern(affine); cairo_set_source(cr, pattern); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } cairo_pattern_destroy(pattern); } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace); cairo_restore(cr); }
static cairo_time_t do_glyphs (double font_size, cairo_antialias_t antialias, cairo_t *cr, int width, int height, int loops) { const char text[] = "the jay, pig, fox, zebra and my wolves quack"; cairo_scaled_font_t *scaled_font; cairo_glyph_t *glyphs = NULL, *glyphs_copy; cairo_text_extents_t extents; cairo_font_options_t *options; cairo_status_t status; double x, y; int num_glyphs, n; options = cairo_font_options_create (); cairo_font_options_set_antialias (options, antialias); cairo_set_font_options (cr, options); cairo_font_options_destroy (options); cairo_select_font_face (cr, "@cairo:", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, font_size); scaled_font = cairo_get_scaled_font (cr); status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., text, -1, &glyphs, &num_glyphs, NULL, NULL, NULL); if (status) return 0; glyphs_copy = cairo_glyph_allocate (num_glyphs); if (glyphs_copy == NULL) { cairo_glyph_free (glyphs); return 0; } cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, &extents); cairo_perf_timer_start (); while (loops--) { y = 0; do { x = 0; do { for (n = 0; n < num_glyphs; n++) { glyphs_copy[n] = glyphs[n]; glyphs_copy[n].x += x; glyphs_copy[n].y += y; } cairo_show_glyphs (cr, glyphs_copy, num_glyphs); x += extents.width; } while (x < width); y += extents.height; } while (y < height); } cairo_perf_timer_stop (); cairo_glyph_free (glyphs); cairo_glyph_free (glyphs_copy); return cairo_perf_timer_elapsed (); }