void VisualizeXML(NewsItem_p pNewsListHead, cairo_t *pCairoHandle) { double dLinkWidth, dLinkHeight; double dWidth, dHeight; double dTitleWidth, dTitleHeight; // TODO cairo_set_operator(pCairoHandle, CAIRO_OPERATOR_OVER); // Query item link width cairo_select_font_face(pCairoHandle, "Helv", 1, 0.2); cairo_set_font_size(pCairoHandle, 0.03); cairo_set_source_rgba(pCairoHandle, 0.6, 0.6, 0.9, 0.8); QueryMultilineTextExtents(pCairoHandle, pNewsListHead->pchItemLink, &dLinkWidth, &dLinkHeight); // Show the multiline text, centered! cairo_select_font_face(pCairoHandle, "Helv", 0, 0); cairo_set_font_size(pCairoHandle, 0.05); cairo_set_source_rgba(pCairoHandle, 1, 1, 1, 1); QueryMultilineTextExtents(pCairoHandle, pNewsListHead->pchItemDescription, &dWidth, &dHeight); if (dWidth<dLinkWidth) dWidth = dLinkWidth; ShowMultilineText(pCairoHandle, pNewsListHead->pchItemDescription, (1*dXAspect-dWidth)/2, (1*dYAspect-dHeight)/2 ); cairo_stroke (pCairoHandle); // Show the item title above it! cairo_select_font_face(pCairoHandle, "Helv", 1, 1); cairo_set_font_size(pCairoHandle, 0.055); cairo_set_source_rgba(pCairoHandle, 1, 1, 0.2, 0.9); QueryMultilineTextExtents(pCairoHandle, pNewsListHead->pchItemTitle, &dTitleWidth, &dTitleHeight); ShowMultilineText(pCairoHandle, pNewsListHead->pchItemTitle, (1*dXAspect-dTitleWidth)/2, (1*dYAspect-dHeight)/2 - 0.02 - dTitleHeight); cairo_stroke (pCairoHandle); // Show the item link under it! cairo_select_font_face(pCairoHandle, "Helv", 1, 0.2); cairo_set_font_size(pCairoHandle, 0.03); cairo_set_source_rgba(pCairoHandle, 0.6, 0.6, 0.9, 0.8); QueryMultilineTextExtents(pCairoHandle, pNewsListHead->pchItemLink, &dLinkWidth, &dLinkHeight); ShowMultilineText(pCairoHandle, pNewsListHead->pchItemLink, (1*dXAspect-dWidth)/2, (1*dYAspect-dHeight)/2 + 0.02 + dHeight); cairo_stroke (pCairoHandle); }
void DrawInputBar(FcitxSkin* sc, InputWindow* inputWindow, boolean vertical, int iCursorPos, FcitxMessages * msgup, FcitxMessages *msgdown , unsigned int * iheight, unsigned int *iwidth) { int i; char *strUp[MAX_MESSAGE_COUNT]; char *strDown[MAX_MESSAGE_COUNT]; int posUpX[MAX_MESSAGE_COUNT], posUpY[MAX_MESSAGE_COUNT]; int posDownX[MAX_MESSAGE_COUNT], posDownY[MAX_MESSAGE_COUNT]; int oldHeight = *iheight, oldWidth = *iwidth; int newHeight = 0, newWidth = 0; int cursor_pos = 0; int inputWidth = 0, outputWidth = 0; int outputHeight = 0; cairo_t *c = NULL; FcitxInputState* input = FcitxInstanceGetInputState(inputWindow->owner->owner); FcitxInstance* instance = inputWindow->owner->owner; FcitxClassicUI* classicui = inputWindow->owner; int iChar = iCursorPos; int strWidth = 0, strHeight = 0; SkinImage *inputimg, *prev, *next; inputimg = LoadImage(sc, sc->skinInputBar.backImg, false); prev = LoadImage(sc, sc->skinInputBar.backArrow, false); next = LoadImage(sc, sc->skinInputBar.forwardArrow, false); if (!FcitxMessagesIsMessageChanged(msgup) && !FcitxMessagesIsMessageChanged(msgdown)) return; inputWidth = 0; int dpi = sc->skinFont.respectDPI? classicui->dpi : 0; FCITX_UNUSED(dpi); #ifdef _ENABLE_PANGO /* special case which only macro unable to handle */ SetFontContext(dummy, inputWindow->owner->font, inputWindow->owner->fontSize > 0 ? inputWindow->owner->fontSize : sc->skinFont.fontSize, dpi); #endif int fontHeight = FontHeightWithContext(inputWindow->c_font[0], dpi); for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) { char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgup, i)); if (trans) strUp[i] = trans; else strUp[i] = FcitxMessagesGetMessageString(msgup, i); posUpX[i] = sc->skinInputBar.marginLeft + inputWidth; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strUp[i], &strWidth, &strHeight); if (sc->skinFont.respectDPI) posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos; else posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - strHeight; inputWidth += strWidth; if (FcitxInputStateGetShowCursor(input)) { int length = strlen(FcitxMessagesGetMessageString(msgup, i)); if (iChar >= 0) { if (iChar < length) { char strTemp[MESSAGE_MAX_LENGTH]; char *strGBKT = NULL; strncpy(strTemp, strUp[i], iChar); strTemp[iChar] = '\0'; strGBKT = strTemp; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strGBKT, &strWidth, &strHeight); cursor_pos = posUpX[i] + strWidth + 2; } iChar -= length; } } } if (iChar >= 0) cursor_pos = inputWidth + sc->skinInputBar.marginLeft; outputWidth = 0; outputHeight = 0; int currentX = 0; int offsetY; if (sc->skinFont.respectDPI) offsetY = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos + fontHeight + (FcitxMessagesGetMessageCount(msgdown) ? sc->skinInputBar.iOutputPos : 0); else offsetY = sc->skinInputBar.marginTop + sc->skinInputBar.iOutputPos - fontHeight; for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) { char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgdown, i)); if (trans) strDown[i] = trans; else strDown[i] = FcitxMessagesGetMessageString(msgdown, i); if (vertical) { /* vertical */ if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) { if (currentX > outputWidth) outputWidth = currentX; if (i != 0) { currentX = 0; } } posDownX[i] = sc->skinInputBar.marginLeft + currentX; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], &strWidth, &strHeight); if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX && i != 0) outputHeight += fontHeight + 2; currentX += strWidth; } else { /* horizontal */ posDownX[i] = sc->skinInputBar.marginLeft + outputWidth; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], &strWidth, &strHeight); outputWidth += strWidth; } posDownY[i] = offsetY + outputHeight; } if (vertical && currentX > outputWidth) outputWidth = currentX; newHeight = offsetY + outputHeight + sc->skinInputBar.marginBottom + (FcitxMessagesGetMessageCount(msgdown) || !sc->skinFont.respectDPI ? fontHeight : 0); newWidth = (inputWidth < outputWidth) ? outputWidth : inputWidth; newWidth += sc->skinInputBar.marginLeft + sc->skinInputBar.marginRight; /* round to ROUND_SIZE in order to decrease resize */ newWidth = (newWidth / ROUND_SIZE) * ROUND_SIZE + ROUND_SIZE; if (vertical) { /* vertical */ newWidth = (newWidth < INPUT_BAR_VMIN_WIDTH) ? INPUT_BAR_VMIN_WIDTH : newWidth; } else { newWidth = (newWidth < INPUT_BAR_HMIN_WIDTH) ? INPUT_BAR_HMIN_WIDTH : newWidth; } *iwidth = newWidth; *iheight = newHeight; EnlargeCairoSurface(&inputWindow->cs_input_back, newWidth, newHeight); if (EnlargeCairoSurface(&inputWindow->cs_input_bar, newWidth, newHeight)) { LoadInputMessage(&classicui->skin, classicui->inputWindow, classicui->font); } if (oldHeight != newHeight || oldWidth != newWidth) { c = cairo_create(inputWindow->cs_input_back); DrawResizableBackground(c, inputimg->image, newHeight, newWidth, sc->skinInputBar.marginLeft, sc->skinInputBar.marginTop, sc->skinInputBar.marginRight, sc->skinInputBar.marginBottom, sc->skinInputBar.fillV, sc->skinInputBar.fillH ); cairo_destroy(c); } c = cairo_create(inputWindow->cs_input_bar); cairo_set_source_surface(c, inputWindow->cs_input_back, 0, 0); cairo_save(c); cairo_rectangle(c, 0, 0, newWidth, newHeight); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_set_operator(c, CAIRO_OPERATOR_OVER); if (FcitxInputStateGetShowCursor(input)) { //画向前向后箭头 if (prev && next) { cairo_set_source_surface(inputWindow->c_back, prev->image, newWidth - sc->skinInputBar.iBackArrowX , sc->skinInputBar.iBackArrowY); if (FcitxCandidateWordHasPrev(FcitxInputStateGetCandidateList(input))) cairo_paint(inputWindow->c_back); else cairo_paint_with_alpha(inputWindow->c_back, 0.5); //画向前箭头 cairo_set_source_surface(inputWindow->c_back, next->image, newWidth - sc->skinInputBar.iForwardArrowX , sc->skinInputBar.iForwardArrowY); if (FcitxCandidateWordHasNext(FcitxInputStateGetCandidateList(input))) cairo_paint(inputWindow->c_back); else cairo_paint_with_alpha(inputWindow->c_back, 0.5); } } for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) { OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strUp[i], posUpX[i], posUpY[i]); if (strUp[i] != FcitxMessagesGetMessageString(msgup, i)) free(strUp[i]); } for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) { OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], posDownX[i], posDownY[i]); if (strDown[i] != FcitxMessagesGetMessageString(msgdown, i)) free(strDown[i]); } int cursorY1, cursorY2; if (sc->skinFont.respectDPI) { cursorY1 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos; cursorY2 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos + fontHeight; } else { cursorY1 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - fontHeight; cursorY2 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos; } //画光标 if (FcitxInputStateGetShowCursor(input)) { cairo_move_to(inputWindow->c_cursor, cursor_pos, cursorY1); cairo_line_to(inputWindow->c_cursor, cursor_pos, cursorY2); cairo_stroke(inputWindow->c_cursor); } ResetFontContext(); cairo_destroy(c); FcitxMessagesSetMessageChanged(msgup, false); FcitxMessagesSetMessageChanged(msgdown, false); }
static svg_cairo_status_t render_to_png (FILE *svg_file, FILE *png_file, double scale, int width, int height) { unsigned int svg_width, svg_height; svg_cairo_status_t status; cairo_t *cr; svg_cairo_t *svgc; cairo_surface_t *surface; double dx = 0, dy = 0; status = svg_cairo_create (&svgc); if (status) { fprintf (stderr, "Failed to create svg_cairo_t. Exiting.\n"); exit(1); } status = svg_cairo_parse_file (svgc, svg_file); if (status) return status; svg_cairo_get_size (svgc, &svg_width, &svg_height); if (width < 0 && height < 0) { width = (svg_width * scale + 0.5); height = (svg_height * scale + 0.5); } else if (width < 0) { scale = (double) height / (double) svg_height; width = (svg_width * scale + 0.5); } else if (height < 0) { scale = (double) width / (double) svg_width; height = (svg_height * scale + 0.5); } else { scale = MIN ((double) width / (double) svg_width, (double) height / (double) svg_height); /* Center the resulting image */ dx = (width - (int) (svg_width * scale + 0.5)) / 2; dy = (height - (int) (svg_height * scale + 0.5)) / 2; } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_restore (cr); cairo_translate (cr, dx, dy); cairo_scale (cr, scale, scale); /* XXX: This probably doesn't need to be here (eventually) */ cairo_set_source_rgb (cr, 1, 1, 1); status = svg_cairo_render (svgc, cr); status = write_surface_to_png_file (surface, png_file); cairo_surface_destroy (surface); cairo_destroy (cr); if (status) return status; svg_cairo_destroy (svgc); return status; }
/** * ppg_visualizer_task_notify_state: * @visualizer: (in): A #PpgVisualizer. * @pspec: (in): A #GParamSpec. * @task: (in): A #PpgTask. * * Handle the "notify::state" signal from @task. Update the visualizer * pattern if necessary. * * Returns: None. * Side effects: None. */ static void ppg_visualizer_task_notify_state (PpgVisualizer *visualizer, GParamSpec *pspec, PpgTask *task) { PpgVisualizerPrivate *priv; cairo_surface_t *surface; PpgTaskState state; cairo_t *cr; gdouble begin_time; gdouble height; gdouble total_width; gdouble span; gdouble width; gdouble x; gdouble y; g_return_if_fail(PPG_IS_VISUALIZER(visualizer)); g_return_if_fail(PPG_IS_TASK(task)); g_return_if_fail(visualizer->priv->surface); priv = visualizer->priv; /* * We don't own the reference, so safe to just drop our pointer. Using * GObjects weak pointers here would be a lot of maintenance pain. */ if (priv->task == task) { priv->task = NULL; } g_object_get(task, "state", &state, "surface", &surface, NULL); if (state == PPG_TASK_SUCCESS) { g_object_get(task, "begin-time", &begin_time, "height", &height, "width", &width, "x", &x, "y", &y, NULL); span = priv->end_time - priv->begin_time; g_object_get(visualizer, "width", &total_width, NULL); x = (begin_time - priv->begin_time) / span * total_width; /* * Only draw what we can do on integer aligned offsets. * * TODO: We need to make sure we render extra area to prevent * a striping effect. */ width -= ceil(x) - x; x = ceil(x); cr = cairo_create(priv->surface); cairo_set_source_surface(cr, surface, x, y); if (cairo_status(cr) != 0) { cairo_destroy(cr); GOTO(failure); } /* * Clip the range of the draw. */ cairo_rectangle(cr, x, y, width, height); cairo_clip_preserve(cr); /* * Clear the draw area. */ cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_fill_preserve(cr); cairo_restore(cr); /* * Fill in the rendered image. */ cairo_fill(cr); cairo_destroy(cr); goo_canvas_item_request_update(GOO_CANVAS_ITEM(visualizer)); } failure: /* * Release our surface that was allocated for the draw request. */ if ((state & PPG_TASK_FINISHED_MASK) != 0) { cairo_surface_destroy(surface); } }
void cairo_context::set_operator(composite_mode_e comp_op) { switch (comp_op) { case clear: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_CLEAR); break; case src: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_SOURCE); break; case dst: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DEST); break; case src_over: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_OVER); break; case dst_over: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DEST_OVER); break; case src_in: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_IN); break; case dst_in: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DEST_IN); break; case src_out: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_OUT); break; case dst_out: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DEST_OUT); break; case src_atop: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_ATOP); break; case dst_atop: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DEST_ATOP); break; case _xor: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_XOR); break; case plus: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_ADD); break; #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0) case multiply: cairo_set_operator(cairo_.get(), CAIRO_OPERATOR_MULTIPLY); break; case screen: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_SCREEN); break; case overlay: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_OVERLAY); break; case darken: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DARKEN); break; case lighten: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_LIGHTEN); break; case color_dodge: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_COLOR_DODGE); break; case color_burn: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_COLOR_BURN); break; case hard_light: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_HARD_LIGHT); break; case soft_light: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_SOFT_LIGHT); break; case difference: cairo_set_operator(cairo_.get(),CAIRO_OPERATOR_DIFFERENCE); break; case exclusion: cairo_set_operator(cairo_.get(), CAIRO_OPERATOR_EXCLUSION); break; #else #warning building against cairo older that 1.10.0, some compositing options are disabled case multiply: case screen: case overlay: case darken: case lighten: case color_dodge: case color_burn: case hard_light: case soft_light: case difference: case exclusion: break; #endif case contrast: case minus: case invert: case invert_rgb: case grain_merge: case grain_extract: case hue: case saturation: case _color: case _value: //case colorize_alpha: break; } // check_object_status_and_throw_exception(*this); }
static gboolean draw_flower (ClutterCanvas *canvas, cairo_t *cr, gint width, gint height, gpointer user_data) { /* No science here, just a hack from toying */ gint i, j; double colors[] = { 0.71, 0.81, 0.83, 1.0, 0.78, 0.57, 0.64, 0.30, 0.35, 0.73, 0.40, 0.39, 0.91, 0.56, 0.64, 0.70, 0.47, 0.45, 0.92, 0.75, 0.60, 0.82, 0.86, 0.85, 0.51, 0.56, 0.67, 1.0, 0.79, 0.58, }; gint size; gint petal_size; gint n_groups; /* Num groups of petals 1-3 */ gint n_petals; /* num of petals 4 - 8 */ gint pm1, pm2; gint idx, last_idx = -1; petal_size = GPOINTER_TO_INT (user_data); size = petal_size * 8; n_groups = rand() % 3 + 1; cairo_set_tolerance (cr, 0.1); /* Clear */ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_translate(cr, size/2, size/2); for (i=0; i<n_groups; i++) { n_petals = rand() % 5 + 4; cairo_save (cr); cairo_rotate (cr, rand() % 6); do { idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3; } while (idx == last_idx); cairo_set_source_rgba (cr, colors[idx], colors[idx+1], colors[idx+2], 0.5); last_idx = idx; /* some bezier randomness */ pm1 = rand() % 20; pm2 = rand() % 4; for (j=1; j<n_petals+1; j++) { cairo_save (cr); cairo_rotate (cr, ((2*M_PI)/n_petals)*j); /* Petals are made up beziers */ cairo_new_path (cr); cairo_move_to (cr, 0, 0); cairo_rel_curve_to (cr, petal_size, petal_size, (pm2+2)*petal_size, petal_size, (2*petal_size) + pm1, 0); cairo_rel_curve_to (cr, 0 + (pm2*petal_size), -petal_size, -petal_size, -petal_size, -((2*petal_size) + pm1), 0); cairo_close_path (cr); cairo_fill (cr); cairo_restore (cr); } petal_size -= rand() % (size/8); cairo_restore (cr); } /* Finally draw flower center */ do { idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3; } while (idx == last_idx); if (petal_size < 0) petal_size = rand() % 10; cairo_set_source_rgba (cr, colors[idx], colors[idx+1], colors[idx+2], 0.5); cairo_arc(cr, 0, 0, petal_size, 0, M_PI * 2); cairo_fill(cr); return TRUE; }
static void gen_faceplate (BITui* ui, const int ww, const int hh) { assert(!ui->m0_faceplate); ui->m0_faceplate = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ww, hh); cairo_t* cr = cairo_create (ui->m0_faceplate); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); const int spc = (int) floorf ((ww - 28) / 28.) & ~1; const int rad = ceilf (spc * .75); const int mid = rint (spc * .75 * .5); const int x0r = rint (ww * .5 + 12 * spc); const int xpr = rint (ww * .5 - 13 * spc); const int spc_s = (int) floorf (ww / 45.) & ~1; const int rad_s = ceilf (spc_s * .75); const int x0r_s = ww * .5 + 20 * spc_s; const int y0 = hh - 60 - rad_s - spc; const int y0_s = hh - 20 - rad_s; const int y0_g = 10; const int y1_g = y0 - 4; const int yh_g = y1_g - y0_g; // grid & annotations -- TODO statically allocate surface const float x0_g = xpr - 2; const float x1_b = x0r + rad + 2; const float x1_g = x1_b + mid + 2; const float yc_g = rintf (y0_g + .5 * yh_g); const float y6_g = rintf (y0_g + yh_g * 2. / 3.); const float y3_g = rintf (y0_g + yh_g / 3.); cairo_rectangle (cr, x1_b, y0_g, mid, y3_g); cairo_set_source_rgba (cr, .8, .5, .1, 1.0); cairo_fill (cr); cairo_rectangle (cr, x1_b, y3_g, mid, y6_g - y3_g); cairo_set_source_rgba (cr, .1, .9, .1, 1.0); cairo_fill (cr); cairo_rectangle (cr, x1_b, y6_g, mid, y1_g - y6_g); cairo_set_source_rgba (cr, .1, .6, .9, 1.0); cairo_fill (cr); cairo_set_line_width (cr, 2); cairo_move_to (cr, x1_b, y0_g); cairo_line_to (cr, x1_b + mid, y0_g); cairo_set_source_rgba (cr, .9, .0, .0, 1.0); cairo_stroke (cr); cairo_move_to (cr, x1_b, y0_g + yh_g); cairo_line_to (cr, x1_b + mid, y0_g + yh_g); cairo_set_source_rgba (cr, .0, .0, .9, 1.0); cairo_stroke (cr); CairoSetSouerceRGBA(c_g80); cairo_set_line_width (cr, 1); cairo_save (cr); double dash = 1; cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); cairo_set_dash (cr, &dash, 1, 0); cairo_move_to (cr, x0_g, y0_g - .5); cairo_line_to (cr, x1_b, y0_g - .5); cairo_stroke (cr); cairo_move_to (cr, x0_g, .5 + yc_g); cairo_line_to (cr, x0_g + spc + 4, .5 + yc_g); cairo_stroke (cr); cairo_move_to (cr, x0_g, .5 + y6_g); cairo_line_to (cr, x1_b, .5 + y6_g); cairo_stroke (cr); cairo_move_to (cr, x0_g, .5 + y3_g); cairo_line_to (cr, x1_b, .5 + y3_g); cairo_stroke (cr); cairo_move_to (cr, x0_g, y1_g + .5); cairo_line_to (cr, x1_b, y1_g + .5); cairo_stroke (cr); cairo_restore (cr); cairo_move_to (cr, 1.5 + rintf (x0r_s - 33 * spc_s), y0_s - 1.5); cairo_line_to (cr, 1.5 + rintf (x0r_s - 33 * spc_s), y0_s + rad_s + 3.5); cairo_line_to (cr, .5 + rintf (x0r_s - 35.5 * spc_s), y0_s + rad_s + 3.5); cairo_stroke (cr); write_text_full (cr, ">1.0", FONT(FONT_M), x0r_s - 33.0 * spc_s, hh - 2, 0, 4, c_wht); write_text_full (cr, "<markup>2<small><sup>-32</sup></small></markup>", FONT(FONT_M), x0r_s + 0.5 * spc_s, hh - 2, 0, 5, c_wht); write_text_full (cr, "<markup>2<small><sup>-24</sup></small></markup>", FONT(FONT_M), x0r_s - 8.0 * spc_s, hh - 2, 0, 5, c_wht); write_text_full (cr, "<markup>2<small><sup>-16</sup></small></markup>", FONT(FONT_M), x0r_s - 16.5 * spc_s, hh - 2, 0, 5, c_wht); write_text_full (cr, "<markup>2<small><sup>-8</sup></small></markup>", FONT(FONT_M), x0r_s - 25.0 * spc_s, hh - 2, 0, 5, c_wht); write_text_full (cr, "<markup>2<small><sup>7</sup></small></markup>", FONT(FONT_M), x0r_s - 40.5 * spc_s, hh - 2, 0, 5, c_wht); write_text_full (cr, "% time bit is set", FONT(FONT_M), x1_g, yc_g, -.5 * M_PI, 8, c_wht); write_text_full (cr, "100%", FONT(FONT_M), x0_g - 2, y0_g, 0, 1, c_wht); write_text_full (cr, "50%", FONT(FONT_M), x0_g - 2, yc_g, 0, 1, c_wht); write_text_full (cr, "0%", FONT(FONT_M), x0_g - 2, y1_g, 0, 1, c_wht); // sep int ysep = .5 * (y0 + rad + y0_s); CairoSetSouerceRGBA(c_g60); cairo_move_to (cr, 15, ysep + .5); cairo_line_to (cr, ww - 30 , ysep + .5); cairo_stroke (cr); write_text_full (cr, "Sign & Mantissa (23bit significand)", FONT(FONT_S), ww * .5, ysep - 2, 0, 5, c_wht); write_text_full (cr, "Full Scale", FONT(FONT_S), ww * .5, ysep + 3, 0, 8, c_wht); write_text_full (cr, ui->nfo, FONT(FONT_M), 2, hh -2, 1.5 * M_PI, 9, c_gry); cairo_destroy (cr); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_pattern_t *gradient, *image; cairo_set_source_rgb (cr, 1,1,1); cairo_paint (cr); cairo_translate (cr, PAD, PAD); /* clip to the unit size */ cairo_rectangle (cr, 0, 0, UNIT_SIZE, UNIT_SIZE); cairo_clip (cr); cairo_rectangle (cr, 0, 0, UNIT_SIZE, UNIT_SIZE); cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_set_line_width (cr, 2); cairo_stroke (cr); /* start a group */ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR); /* draw a gradient background */ cairo_save (cr); cairo_translate (cr, INNER_PAD, INNER_PAD); cairo_new_path (cr); cairo_rectangle (cr, 0, 0, UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2)); gradient = cairo_pattern_create_linear (UNIT_SIZE - (INNER_PAD*2), 0, UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2)); cairo_pattern_add_color_stop_rgba (gradient, 0.0, 0.3, 0.3, 0.3, 1.0); cairo_pattern_add_color_stop_rgba (gradient, 1.0, 1.0, 1.0, 1.0, 1.0); cairo_set_source (cr, gradient); cairo_pattern_destroy (gradient); cairo_fill (cr); cairo_restore (cr); /* draw diamond */ cairo_move_to (cr, UNIT_SIZE / 2, 0); cairo_line_to (cr, UNIT_SIZE , UNIT_SIZE / 2); cairo_line_to (cr, UNIT_SIZE / 2, UNIT_SIZE); cairo_line_to (cr, 0 , UNIT_SIZE / 2); cairo_close_path (cr); cairo_set_source_rgba (cr, 0, 0, 1, 1); cairo_fill (cr); /* draw circle */ cairo_arc (cr, UNIT_SIZE / 2, UNIT_SIZE / 2, UNIT_SIZE / 3.5, 0, M_PI * 2); cairo_set_source_rgba (cr, 1, 0, 0, 1); cairo_fill (cr); /* and put the image on top */ cairo_translate (cr, UNIT_SIZE/2 - 8, UNIT_SIZE/2 - 8); image = argb32_source (); cairo_set_source (cr, image); cairo_pattern_destroy (image); cairo_paint (cr); cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); return CAIRO_TEST_SUCCESS; }
imageObj* createImageCairo(int width, int height, outputFormatObj *format,colorObj* bg) { imageObj *image = NULL; cairo_renderer *r=NULL; if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode!= MS_IMAGEMODE_RGBA) { msSetError(MS_MISCERR, "Cairo driver only supports RGB or RGBA pixel models.","msImageCreateCairo()"); return image; } if (width > 0 && height > 0) { image = (imageObj *) calloc(1, sizeof(imageObj)); r = (cairo_renderer*)calloc(1,sizeof(cairo_renderer)); if(!strcasecmp(format->driver,"cairo/pdf")) { r->outputStream = (bufferObj*)malloc(sizeof(bufferObj)); msBufferInit(r->outputStream); r->surface = cairo_pdf_surface_create_for_stream( _stream_write_fn, r->outputStream, width,height); } else if(!strcasecmp(format->driver,"cairo/svg")) { r->outputStream = (bufferObj*)malloc(sizeof(bufferObj)); msBufferInit(r->outputStream); r->surface = cairo_svg_surface_create_for_stream( _stream_write_fn, r->outputStream, width,height); } else if(!strcasecmp(format->driver,"cairo/winGDI") && format->device) { #if CAIRO_HAS_WIN32_SURFACE r->outputStream = NULL; r->surface = cairo_win32_surface_create(format->device); #else msSetError(MS_RENDERERERR, "Cannot create cairo image. Cairo was not compiled with support for the win32 backend.", "msImageCreateCairo()"); #endif } else if(!strcasecmp(format->driver,"cairo/winGDIPrint") && format->device) { #if CAIRO_HAS_WIN32_SURFACE r->outputStream = NULL; r->surface = cairo_win32_printing_surface_create(format->device); #else msSetError(MS_RENDERERERR, "Cannot create cairo image. Cairo was not compiled with support for the win32 backend.", "msImageCreateCairo()"); #endif } else { r->outputStream = NULL; r->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); } r->cr = cairo_create(r->surface); if(format->transparent || !bg || !MS_VALID_COLOR(*bg)) { r->use_alpha = 1; cairo_set_source_rgba (r->cr, 0,0,0,0); } else { r->use_alpha = 0; msCairoSetSourceColor(r->cr,bg); } cairo_save (r->cr); cairo_set_operator (r->cr, CAIRO_OPERATOR_SOURCE); cairo_paint (r->cr); cairo_restore (r->cr); cairo_set_line_cap (r->cr,CAIRO_LINE_CAP_ROUND); cairo_set_line_join(r->cr,CAIRO_LINE_JOIN_ROUND); image->img.plugin = (void*)r; } else { msSetError(MS_RENDERERERR, "Cannot create cairo image of size %dx%d.", "msImageCreateCairo()", width, height); } return image; }
static GstFlowReturn gst_cairo_time_overlay_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) { GstCairoTimeOverlay *timeoverlay; int width; int height; int b_width; int stride_y, stride_u, stride_v; char *string; int i, j; unsigned char *image; cairo_text_extents_t extents; guint8 *dest, *src; cairo_surface_t *font_surface; cairo_t *text_cairo; GstFlowReturn ret = GST_FLOW_OK; timeoverlay = GST_CAIRO_TIME_OVERLAY (trans); gst_buffer_copy_metadata (out, in, GST_BUFFER_COPY_TIMESTAMPS); src = GST_BUFFER_DATA (in); dest = GST_BUFFER_DATA (out); width = timeoverlay->width; height = timeoverlay->height; /* create surface for font rendering */ /* FIXME: preparation of the surface could also be done once when settings * change */ image = g_malloc (4 * width * timeoverlay->text_height); font_surface = cairo_image_surface_create_for_data (image, CAIRO_FORMAT_ARGB32, width, timeoverlay->text_height, width * 4); text_cairo = cairo_create (font_surface); cairo_surface_destroy (font_surface); font_surface = NULL; /* we draw a rectangle because the compositing on the buffer below * doesn't do alpha */ cairo_save (text_cairo); cairo_rectangle (text_cairo, 0, 0, width, timeoverlay->text_height); cairo_set_source_rgba (text_cairo, 0, 0, 0, 1); cairo_set_operator (text_cairo, CAIRO_OPERATOR_SOURCE); cairo_fill (text_cairo); cairo_restore (text_cairo); string = gst_cairo_time_overlay_print_smpte_time (GST_BUFFER_TIMESTAMP (in)); cairo_save (text_cairo); cairo_select_font_face (text_cairo, "monospace", 0, 0); cairo_set_font_size (text_cairo, 20); cairo_text_extents (text_cairo, string, &extents); cairo_set_source_rgb (text_cairo, 1, 1, 1); cairo_move_to (text_cairo, 0, timeoverlay->text_height - 2); cairo_show_text (text_cairo, string); g_free (string); cairo_restore (text_cairo); /* blend width; should retain a max text width so it doesn't jitter */ b_width = extents.width; if (b_width > width) b_width = width; stride_y = GST_VIDEO_I420_Y_ROWSTRIDE (width); stride_u = GST_VIDEO_I420_U_ROWSTRIDE (width); stride_v = GST_VIDEO_I420_V_ROWSTRIDE (width); memcpy (dest, src, GST_BUFFER_SIZE (in)); for (i = 0; i < timeoverlay->text_height; i++) { for (j = 0; j < b_width; j++) { ((unsigned char *) dest)[i * stride_y + j] = image[(i * width + j) * 4 + 0]; } } for (i = 0; i < timeoverlay->text_height / 2; i++) { memset (dest + GST_VIDEO_I420_U_OFFSET (width, height) + i * stride_u, 128, b_width / 2); memset (dest + GST_VIDEO_I420_V_OFFSET (width, height) + i * stride_v, 128, b_width / 2); } cairo_destroy (text_cairo); text_cairo = NULL; g_free (image); return ret; }
bool TextAsset::load() { // Set up a temporary Cairo surface/context for text measurement cairo_surface_t* probeSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); if (cairo_surface_status(probeSurface) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not create Cairo surface\n"); _error = true; return false; } cairo_t* probeContext = cairo_create(probeSurface); if (cairo_status(probeContext) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not create Cairo context\n"); _error = true; return false; } // Text rectangle drawn within border const int idealWidth = _maxSize.width - _marginLeft - _marginRight; const Size textRegion(idealWidth, _maxSize.height - _marginTop - _marginBottom); const float fontSize = primaryFontSize(probeContext, textRegion); const std::string fontDesc = _fontName + " " + boost::lexical_cast<std::string>(fontSize); PangoFontDescription* fontDescription = pango_font_description_from_string(fontDesc.c_str()); const std::string req_desc_str(pango_font_description_to_string(fontDescription)); PangoFontMap* fontMap = pango_cairo_font_map_new_for_font_type(CAIRO_FONT_TYPE_FT); PangoContext* pango_context = pango_font_map_create_context(fontMap); // TODO: Does this need to be freed or does the context take it with it? PangoFont* pangoFont = pango_font_map_load_font(fontMap, pango_context, fontDescription); PangoFontDescription* reverseDescription = pango_font_describe(pangoFont); const std::string match_desc_str(pango_font_description_to_string(reverseDescription)); pango_font_description_free(reverseDescription); g_object_unref(pango_context); if (req_desc_str.find(match_desc_str) == std::string::npos) { fprintf(stderr, "Warning: Unable to correctly match font \"%s\", using " "\"%s\" instead.\n", req_desc_str.c_str(), match_desc_str.c_str()); } float shadowXOffset = 0; float shadowYOffset = 0; if (_dropShadow) { shadowXOffset = _dropShadowOffset.x() * CLIENT_TO_SERVER_SCALE * fontSize; shadowYOffset = _dropShadowOffset.y() * CLIENT_TO_SERVER_SCALE * fontSize; } Rect tight; const Size textSize = computeSizeOfText(probeContext, _textContent, idealWidth, fontDescription, &tight); const Size imageSize = imageSizeForTextSize(tight.size, shadowXOffset, shadowYOffset); // Tear down scratch contexts cairo_destroy(probeContext); cairo_surface_destroy(probeSurface); const int width = imageSize.width; const int height = imageSize.height; // Configure the actual Cairo drawing surface/context now that we know the final resolution cairo_surface_t* cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status(cairoSurface) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not create Cairo surface\n"); _error = true; return false; } cairo_t* cairoContext = cairo_create(cairoSurface); // Flip the context like in the iOS version. // This fixes flipped filters associated with text assets. cairo_translate(cairoContext, 0.0, height); cairo_scale(cairoContext, 1.0, -1.0); if (cairo_status(cairoContext) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not create Cairo context\n"); _error = true; return false; } // Fill the box with the background color cairo_save(cairoContext); cairo_set_operator(cairoContext, CAIRO_OPERATOR_SOURCE); const mf::Color& bgColor(_style->getBackgroundColor()); cairo_set_source_rgba(cairoContext, bgColor.red, bgColor.green, bgColor.blue, bgColor.alpha); if (_shape == 0) { if (_cornerWidth > 0 && _cornerHeight > 0) { // TODO: Support independent corner width and height drawRoundedRect(cairoContext, 0, 0, imageSize.width, imageSize.height, _cornerWidth); } else { cairo_paint(cairoContext); if (_strokeThickness > 0.0f) { drawStrokedRect(cairoContext, 0, 0, imageSize.width, imageSize.height, _strokeThickness); } } } else if (_shape == 1) { strokeFillBezier(cairoContext, 0, 0, imageSize.width, imageSize.height, _strokeThickness); } cairo_restore(cairoContext); const Rect textRect = textRectForTextSize(textSize, imageSize, tight); if (_dropShadow) { const Rect shadowRect(textRect.x + shadowXOffset, textRect.y + shadowYOffset, textRect.size.width, textRect.size.height); cairo_set_source_rgba(cairoContext, _dropShadowColor.red, _dropShadowColor.green, _dropShadowColor.blue, _dropShadowColor.alpha); drawText(cairoContext, _textContent, shadowRect, fontDescription, false); } cairo_set_source_rgba(cairoContext, _textColor.red, _textColor.green, _textColor.blue, _textColor.alpha); if (_textColor.alpha > 0.0) { drawText(cairoContext, _textContent, textRect, fontDescription, true); } // DEBUG: Dump rendered text to an image // cairo_surface_write_to_png(cairoSurface, "text.png"); // Transfer Cairo surface to OpenGL texture GLubyte* imageData = static_cast<GLubyte *>(cairo_image_surface_get_data(cairoSurface)); glGenTextures(1, &_texture.textureID); glBindTexture(GL_TEXTURE_2D, _texture.textureID); _texture.width = width; _texture.height = height; _texture.s = 1.0; _texture.t = 1.0; _texture.aspect = static_cast<GLfloat>(_texture.width) / _texture.height; _texture.flipImage = true; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #ifdef GL_BGRA // Allocate and transfer data into texture (allow OpenGL swizzling) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, imageData); #else // Cairo uses a BGRA layout, OpenGL ES 2.0 does not support GL_BGRA as a // source format so manually perform swizzling. for (size_t i = 0; i < width * height * BYTES_PER_PIXEL; i += BYTES_PER_PIXEL) { std::swap(imageData[i], imageData[i + 2]); } // Allocate and transfer data into texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); #endif // Clean up pango_font_description_free(fontDescription); cairo_destroy(cairoContext); cairo_surface_destroy(cairoSurface); g_object_unref(pangoFont); _loading = false; _loaded = !_loading && !_error; return true; }
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color) { if (paintingDisabled()) return; unsigned rectCount = rects.size(); cairo_t* cr = platformContext()->cr(); cairo_save(cr); cairo_push_group(cr); cairo_new_path(cr); #if PLATFORM(GTK) #ifdef GTK_API_VERSION_2 GdkRegion* reg = gdk_region_new(); #else cairo_region_t* reg = cairo_region_create(); #endif for (unsigned i = 0; i < rectCount; i++) { #ifdef GTK_API_VERSION_2 GdkRectangle rect = rects[i]; gdk_region_union_with_rect(reg, &rect); #else cairo_rectangle_int_t rect = rects[i]; cairo_region_union_rectangle(reg, &rect); #endif } gdk_cairo_region(cr, reg); #ifdef GTK_API_VERSION_2 gdk_region_destroy(reg); #else cairo_region_destroy(reg); #endif #else int radius = (width - 1) / 2; Path path; for (unsigned i = 0; i < rectCount; ++i) { if (i > 0) path.clear(); path.addRoundedRect(rects[i], FloatSize(radius, radius)); appendWebCorePathToCairoContext(cr, path); } #endif Color ringColor = color; adjustFocusRingColor(ringColor); adjustFocusRingLineWidth(width); setSourceRGBAFromColor(cr, ringColor); cairo_set_line_width(cr, width); setPlatformStrokeStyle(focusRingStrokeStyle()); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_stroke_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); cairo_fill(cr); cairo_pop_group_to_source(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_paint(cr); cairo_restore(cr); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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)); }
void render_hex (cairo_t *cr, int x, int y, int w) { cairo_pattern_t *pat; static float hexrot = 0; int r1; float scale; cairo_save(cr); cairo_set_line_width(cr, 1); cairo_set_source_rgb(cr, ORANGE); scale = 2.5; r1 = ((w)/2 * sqrt(3)); cairo_translate (cr, x, y); cairo_rotate (cr, hexrot * (M_PI/180.0)); cairo_translate (cr, -(w/2), -r1); cairo_move_to (cr, 0, 0); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); hexrot += 1.5; cairo_fill (cr); cairo_restore(cr); cairo_save(cr); cairo_set_line_width(cr, 1.5); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_set_source_rgb(cr, GREY); cairo_translate (cr, x, y); cairo_rotate (cr, hexrot * (M_PI/180.0)); cairo_translate (cr, -((w * scale)/2), -r1 * scale); cairo_scale(cr, scale, scale); cairo_move_to (cr, 0, 0); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_rel_line_to (cr, w, 0); cairo_rotate (cr, 60 * (M_PI/180.0)); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); pat = cairo_pattern_create_radial (w/2, r1, 3, w/2, r1, r1*scale); cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 1, 1); cairo_pattern_add_color_stop_rgba (pat, 0.4, 0, 0, 0, 0); cairo_set_source (cr, pat); cairo_fill (cr); cairo_pattern_destroy (pat); cairo_restore(cr); }
static void draw_line(struct clickdot *clickdot, cairo_t *cr, struct rectangle *allocation) { cairo_t *bcr; cairo_surface_t *tmp_buffer = NULL; if (clickdot->reset) { tmp_buffer = clickdot->buffer; clickdot->buffer = NULL; clickdot->line.x = -1; clickdot->line.y = -1; clickdot->line.old_x = -1; clickdot->line.old_y = -1; clickdot->reset = 0; } if (clickdot->buffer == NULL) { clickdot->buffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation->width, allocation->height); bcr = cairo_create(clickdot->buffer); cairo_set_source_rgba(bcr, 0, 0, 0, 0); cairo_rectangle(bcr, 0, 0, allocation->width, allocation->height); cairo_fill(bcr); } else bcr = cairo_create(clickdot->buffer); if (tmp_buffer) { cairo_set_source_surface(bcr, tmp_buffer, 0, 0); cairo_rectangle(bcr, 0, 0, allocation->width, allocation->height); cairo_clip(bcr); cairo_paint(bcr); cairo_surface_destroy(tmp_buffer); } if (clickdot->line.x != -1 && clickdot->line.y != -1) { if (clickdot->line.old_x != -1 && clickdot->line.old_y != -1) { cairo_set_line_width(bcr, 2.0); cairo_set_source_rgb(bcr, 1, 1, 1); cairo_translate(bcr, -allocation->x, -allocation->y); cairo_move_to(bcr, clickdot->line.old_x, clickdot->line.old_y); cairo_line_to(bcr, clickdot->line.x, clickdot->line.y); cairo_stroke(bcr); } clickdot->line.old_x = clickdot->line.x; clickdot->line.old_y = clickdot->line.y; } cairo_destroy(bcr); cairo_set_source_surface(cr, clickdot->buffer, allocation->x, allocation->y); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_rectangle(cr, allocation->x, allocation->y, allocation->width, allocation->height); cairo_clip(cr); cairo_paint(cr); }
static void scale_render(GpsdViewerOsd *self, OsmGpsMap *map) { GpsdViewerOsdScale *scale = self->priv->scale; if(!scale->surface) return; /* this only needs to be rendered if the zoom or latitude has changed */ gint zoom; gfloat lat; g_object_get(G_OBJECT(map), "zoom", &zoom, "latitude", &lat, NULL); if(zoom == scale->zoom && lat == scale->lat) return; scale->zoom = zoom; scale->lat = lat; float m_per_pix = osm_gps_map_get_scale(map); /* first fill with transparency */ g_assert(scale->surface); cairo_t *cr = cairo_create(scale->surface); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0); // pink for testing: cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); /* determine the size of the scale width in meters */ float width = (GPSD_VIEWER_OSD_SCALE_W-GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6) * m_per_pix; /* scale this to useful values */ int exp = logf(width)*M_LOG10E; int mant = width/pow(10,exp); int width_metric = mant * pow(10,exp); char *dist_str = NULL; if(width_metric<1000) dist_str = g_strdup_printf("%u m", width_metric); else dist_str = g_strdup_printf("%u km", width_metric/1000); width_metric /= m_per_pix; /* and now the hard part: scale for useful imperial values :-( */ /* try to convert to feet, 1ft == 0.3048 m */ width /= 0.3048; float imp_scale = 0.3048; char *dist_imp_unit = "ft"; if(width >= 100) { /* 1yd == 3 feet */ width /= 3.0; imp_scale *= 3.0; dist_imp_unit = "yd"; if(width >= 1760.0) { /* 1mi == 1760 yd */ width /= 1760.0; imp_scale *= 1760.0; dist_imp_unit = "mi"; } } /* also convert this to full tens/hundreds */ exp = logf(width)*M_LOG10E; mant = width/pow(10,exp); int width_imp = mant * pow(10,exp); char *dist_str_imp = g_strdup_printf("%u %s", width_imp, dist_imp_unit); /* convert back to pixels */ width_imp *= imp_scale; width_imp /= m_per_pix; cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); cairo_text_extents_t extents; cairo_text_extents (cr, dist_str, &extents); cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_set_line_width (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6); cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD, GPSD_VIEWER_OSD_SCALE_H2-GPSD_VIEWER_OSD_SCALE_FD); cairo_text_path (cr, dist_str); cairo_stroke (cr); cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD, GPSD_VIEWER_OSD_SCALE_H2+GPSD_VIEWER_OSD_SCALE_FD + extents.height); cairo_text_path (cr, dist_str_imp); cairo_stroke (cr); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD, GPSD_VIEWER_OSD_SCALE_H2-GPSD_VIEWER_OSD_SCALE_FD); cairo_show_text (cr, dist_str); cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD, GPSD_VIEWER_OSD_SCALE_H2+GPSD_VIEWER_OSD_SCALE_FD + extents.height); cairo_show_text (cr, dist_str_imp); g_free(dist_str); g_free(dist_str_imp); /* draw white line */ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); cairo_set_line_width (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/3); cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_M); cairo_rel_line_to (cr, 0, GPSD_VIEWER_OSD_SCALE_TICK); cairo_rel_line_to (cr, width_metric, 0); cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK); cairo_stroke(cr); cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_I); cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK); cairo_rel_line_to (cr, width_imp, 0); cairo_rel_line_to (cr, 0, +GPSD_VIEWER_OSD_SCALE_TICK); cairo_stroke(cr); /* draw black line */ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); cairo_set_line_width (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6); cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_M); cairo_rel_line_to (cr, 0, GPSD_VIEWER_OSD_SCALE_TICK); cairo_rel_line_to (cr, width_metric, 0); cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK); cairo_stroke(cr); cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_I); cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK); cairo_rel_line_to (cr, width_imp, 0); cairo_rel_line_to (cr, 0, +GPSD_VIEWER_OSD_SCALE_TICK); cairo_stroke(cr); cairo_destroy(cr); }
void _gtk_pixel_cache_set_position (GtkPixelCache *cache, cairo_rectangle_int_t *view_rect, cairo_rectangle_int_t *canvas_rect) { cairo_rectangle_int_t r, view_pos; cairo_region_t *copy_region; int new_surf_x, new_surf_y; cairo_t *backing_cr; if (cache->surface == NULL) return; /* Position of view inside canvas */ view_pos.x = -canvas_rect->x; view_pos.y = -canvas_rect->y; view_pos.width = view_rect->width; view_pos.height = view_rect->height; /* Reposition so all is visible */ if (view_pos.x < cache->surface_x || view_pos.x + view_pos.width > cache->surface_x + cache->surface_w || view_pos.y < cache->surface_y || view_pos.y + view_pos.height > cache->surface_y + cache->surface_h) { new_surf_x = cache->surface_x; if (view_pos.x < cache->surface_x) new_surf_x = MAX (view_pos.x + view_pos.width - cache->surface_w, 0); else if (view_pos.x + view_pos.width > cache->surface_x + cache->surface_w) new_surf_x = MIN (view_pos.x, canvas_rect->width - cache->surface_w); new_surf_y = cache->surface_y; if (view_pos.y < cache->surface_y) new_surf_y = MAX (view_pos.y + view_pos.height - cache->surface_h, 0); else if (view_pos.y + view_pos.height > cache->surface_y + cache->surface_h) new_surf_y = MIN (view_pos.y, canvas_rect->height - cache->surface_h); r.x = 0; r.y = 0; r.width = cache->surface_w; r.height = cache->surface_h; copy_region = cairo_region_create_rectangle (&r); if (cache->surface_dirty) { cairo_region_subtract (copy_region, cache->surface_dirty); cairo_region_destroy (cache->surface_dirty); cache->surface_dirty = NULL; } cairo_region_translate (copy_region, cache->surface_x - new_surf_x, cache->surface_y - new_surf_y); cairo_region_intersect_rectangle (copy_region, &r); backing_cr = cairo_create (cache->surface); gdk_cairo_region (backing_cr, copy_region); cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE); cairo_clip (backing_cr); cairo_push_group (backing_cr); cairo_set_source_surface (backing_cr, cache->surface, cache->surface_x - new_surf_x, cache->surface_y - new_surf_y); cairo_paint (backing_cr); cairo_pop_group_to_source (backing_cr); cairo_paint (backing_cr); cairo_destroy (backing_cr); cache->surface_x = new_surf_x; cache->surface_y = new_surf_y; cairo_region_xor_rectangle (copy_region, &r); cache->surface_dirty = copy_region; } }
void _cairo_paint_grid (cairo_t *cr, cairo_rectangle_int_t *rectangle, GthGridType grid_type) { double ux, uy; cairo_save (cr); ux = uy = 1.0; cairo_device_to_user_distance (cr, &ux, &uy); cairo_set_line_width (cr, MAX (ux, uy)); cairo_rectangle (cr, rectangle->x - ux + 0.5, rectangle->y - uy + 0.5, rectangle->width + (ux * 2), rectangle->height + (uy * 2)); cairo_clip (cr); #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 2) cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE); #endif cairo_rectangle (cr, rectangle->x + 0.5, rectangle->y + 0.5, rectangle->width - 0.5, rectangle->height - 0.5); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_stroke (cr); if (grid_type == GTH_GRID_NONE) { cairo_restore (cr); return; } if (grid_type == GTH_GRID_THIRDS) { int i; cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60); for (i = 1; i < 3; i++) { cairo_move_to (cr, rectangle->x + rectangle->width * i / 3 + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + rectangle->width * i / 3 + 0.5, rectangle->y + rectangle->height - 0.5); cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 3 + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 3 + 0.5); } cairo_stroke (cr); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10); for (i = 1; i < 9; i++) { if (i % 3 == 0) continue; cairo_move_to (cr, rectangle->x + rectangle->width * i / 9 + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + rectangle->width * i / 9 + 0.5, rectangle->y + rectangle->height - 0.5); cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 9 + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 9 + 0.5); } cairo_stroke (cr); } else if (grid_type == GTH_GRID_GOLDEN) { cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60); int grid_x0, grid_x1, grid_x2, grid_x3; int grid_y0, grid_y1, grid_y2, grid_y3; int x_delta, y_delta; grid_x0 = rectangle->x; grid_x3 = rectangle->x + rectangle->width; grid_y0 = rectangle->y; grid_y3 = rectangle->y + rectangle->height; x_delta = rectangle->width * GOLDER_RATIO_FACTOR; y_delta = rectangle->height * GOLDER_RATIO_FACTOR; grid_x1 = grid_x0 + x_delta; grid_x2 = grid_x3 - x_delta; grid_y1 = grid_y0 + y_delta; grid_y2 = grid_y3 - y_delta; cairo_move_to (cr, grid_x1 + 0.5, grid_y0 + 0.5); cairo_line_to (cr, grid_x1 + 0.5, grid_y3 + 0.5); if (x_delta < rectangle->width / 2) { cairo_move_to (cr, grid_x2 + 0.5, grid_y0 + 0.5); cairo_line_to (cr, grid_x2 + 0.5, grid_y3 + 0.5); } cairo_move_to (cr, grid_x0 + 0.5, grid_y1 + 0.5); cairo_line_to (cr, grid_x3 + 0.5, grid_y1 + 0.5); if (y_delta < rectangle->height / 2) { cairo_move_to (cr, grid_x0 + 0.5, grid_y2 + 0.5); cairo_line_to (cr, grid_x3 + 0.5, grid_y2 + 0.5); } cairo_stroke (cr); } else if (grid_type == GTH_GRID_CENTER) { int i; cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60); cairo_move_to (cr, rectangle->x + rectangle->width / 2 + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + rectangle->width / 2 + 0.5, rectangle->y + rectangle->height - 0.5); cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height / 2 + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height / 2 + 0.5); cairo_stroke (cr); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10); for (i = 1; i < 4; i++) { if (i == 2) continue; cairo_move_to (cr, rectangle->x + rectangle->width * i / 4 + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + rectangle->width * i / 4 + 0.5, rectangle->y + rectangle->height - 0.5); cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 4 + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 4 + 0.5); } cairo_stroke (cr); } else if (grid_type == GTH_GRID_UNIFORM) { int x; int y; if (rectangle->width / GRID_STEP_3 <= MAX_GRID_LINES) { cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.40); for (x = GRID_STEP_3; x < rectangle->width; x += GRID_STEP_3) { cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5); } for (y = GRID_STEP_3; y < rectangle->height; y += GRID_STEP_3) { cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5); } cairo_stroke (cr); } if (rectangle->width / GRID_STEP_2 <= MAX_GRID_LINES) { cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.20); for (x = GRID_STEP_2; x < rectangle->width; x += GRID_STEP_2) { if (x % GRID_STEP_3 == 0) continue; cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5); } for (y = GRID_STEP_2; y < rectangle->height; y += GRID_STEP_2) { if (y % GRID_STEP_3 == 0) continue; cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5); } cairo_stroke (cr); } if (rectangle->width / GRID_STEP_1 <= MAX_GRID_LINES) { cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10); for (x = GRID_STEP_1; x < rectangle->width; x += GRID_STEP_1) { if (x % GRID_STEP_2 == 0) continue; cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5); cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5); } for (y = GRID_STEP_1; y < rectangle->height; y += GRID_STEP_1) { if (y % GRID_STEP_2 == 0) continue; cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5); cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5); } } cairo_stroke (cr); } cairo_restore (cr); }
int guacenc_handle_copy(guacenc_display* display, int argc, char** argv) { /* Verify argument count */ if (argc < 9) { guacenc_log(GUAC_LOG_WARNING, "\"copy\" instruction incomplete"); return 1; } /* Parse arguments */ int sindex = atoi(argv[0]); int sx = atoi(argv[1]); int sy = atoi(argv[2]); int width = atoi(argv[3]); int height = atoi(argv[4]); int mask = atoi(argv[5]); int dindex = atoi(argv[6]); int dx = atoi(argv[7]); int dy = atoi(argv[8]); /* Pull buffer of source layer/buffer */ guacenc_buffer* src = guacenc_display_get_related_buffer(display, sindex); if (src == NULL) return 1; /* Pull buffer of destination layer/buffer */ guacenc_buffer* dst = guacenc_display_get_related_buffer(display, dindex); if (dst == NULL) return 1; /* Expand the destination buffer as necessary to fit the draw operation */ if (dst->autosize) guacenc_buffer_fit(dst, dx + width, dy + height); /* Copy rectangle from source to destination */ if (src->surface != NULL && dst->cairo != NULL) { /* If surfaces are different, no need to copy */ cairo_surface_t* surface; if (src != dst) surface = src->surface; /* Otherwise, copy to a temporary surface */ else { /* Create new surface to hold the source rect */ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); /* Copy relevant rectangle from source surface */ cairo_t* cairo = cairo_create(surface); cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(cairo, src->surface, -sx, -sy); cairo_paint(cairo); cairo_destroy(cairo); /* Source coordinates are now (0, 0) */ sx = sy = 0; } /* Perform copy */ cairo_set_operator(dst->cairo, guacenc_display_cairo_operator(mask)); cairo_set_source_surface(dst->cairo, surface, dx - sx, dy - sy); cairo_rectangle(dst->cairo, dx, dy, width, height); cairo_fill(dst->cairo); /* Destroy temporary surface if it was created */ if (surface != src->surface) cairo_surface_destroy(surface); } return 0; }
static gboolean budgie_popover_draw(GtkWidget *widget, cairo_t *cr, gboolean draw) { BudgiePopover *self = BUDGIE_POPOVER(widget); GtkStyleContext *style; GtkAllocation alloc; GtkPositionType gap_side; GdkRGBA color; gdouble x, y, tail_height, gap_width; gdouble margin, width, height, gap1, gap2; x = 0; y = 0; tail_height = 12; gap_width = 24; margin = 11; x += margin; y += margin; style = gtk_widget_get_style_context(widget); gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME); gtk_widget_get_allocation(widget, &alloc); /* Have parent class do drawing, so we gain shadows */ ((GtkWidgetClass*)budgie_popover_parent_class)->draw(widget, cr); /* Remove height of tail, and margin, from our rendered size */ width = alloc.width; height = alloc.height - tail_height; height -= margin; width -= margin*2; cairo_set_operator(cr, CAIRO_OPERATOR_OVER); gap1 = (alloc.width/2)-(gap_width/2); gap1 = self->widg_x; gap2 = gap1 + gap_width; gap2 -= margin; gap_side = self->top == TRUE ? GTK_POS_TOP : GTK_POS_BOTTOM; /* Render a gap in the bottom center for our arrow */ gtk_render_frame_gap(style, cr, x, y, width, height, gap_side, gap1, gap2); /* Fill in the background (pre-clip) */ gtk_render_background(style, cr, x, y, width, height); /* Clip to the tail, fill in the arrow background */ cairo_save(cr); if (self->top) budgie_tail_path(cr, gap1, gap_width, y-margin, tail_height, self->top); else budgie_tail_path(cr, gap1, gap_width, height+margin, tail_height, self->top); cairo_clip(cr); if (self->top) gtk_render_background(style, cr, x, y-tail_height, alloc.width, alloc.height); else gtk_render_background(style, cr, x, y, alloc.width, alloc.height); cairo_restore(cr); /* Draw in the border */ gtk_style_context_get_border_color(style, gtk_widget_get_state_flags(widget), &color); gdk_cairo_set_source_rgba(cr, &color); cairo_set_line_width(cr, 1); if (self->top) budgie_tail_path(cr, gap1, gap_width, y-margin, tail_height, self->top); else budgie_tail_path(cr, gap1, gap_width, height+margin, tail_height, self->top); cairo_stroke(cr); /* Draw children */ gtk_container_propagate_draw(GTK_CONTAINER(widget), gtk_bin_get_child(GTK_BIN(widget)), cr); return TRUE; }
static bool expose_event (RobWidget* rw, cairo_t* cr, cairo_rectangle_t *ev) { BITui* ui = (BITui*)GET_HANDLE(rw); cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); cairo_clip (cr); const int ww = rw->area.width; const int hh = rw->area.height; CairoSetSouerceRGBA(c_g30); cairo_rectangle (cr, 0, 0, ww, hh); cairo_fill (cr); if (!ui->m0_faceplate) { gen_faceplate (ui, ww, hh); } const int spc = (int) floorf ((ww - 28) / 28.) & ~1; const int rad = ceilf (spc * .75); const int x0r = rint (ww * .5 + 12 * spc); const int xpr = rint (ww * .5 - 13 * spc); const int spc_s = (int) floorf (ww / 45.) & ~1; const int rad_s = ceilf (spc_s * .75); const int x0r_s = ww * .5 + 20 * spc_s; const int y0 = hh - 60 - rad_s - spc; const int y0_s = hh - 20 - rad_s; const int y0_g = 10; const int y1_g = y0 - 4; const int yh_g = y1_g - y0_g; // draw distribution if ((int)ui->integration_spl == ui->f_zero) { // all blank draw_bit_dist (cr, xpr, y0_g, rad, yh_g, -1); for (int k = 0; k < 23; ++k) { const float xp = x0r - rintf (spc * (.5 * (k / 8) + k)); draw_bit_dist (cr, xp, y0_g, rad, yh_g, -1); } } else { const float scnt = ui->integration_spl; draw_bit_dist (cr, xpr, y0_g, rad, yh_g, ui->f_pos / scnt); for (int k = 0; k < 23; ++k) { const float xp = x0r - rintf (spc * (.5 * (k / 8) + k)); const float v = ui->flt[k + BIM_DSET] / scnt; draw_bit_dist (cr, xp, y0_g, rad, yh_g, v); } } cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_surface(cr, ui->m0_faceplate, 0, 0); cairo_paint (cr); /* quick glance boxes */ // sign - bit draw_bit_box (ui, cr, xpr, y0, rad, -1, ui->f_pos); // "+" sign const float mid = .5 + rintf (spc * .75 * .5); const float span = ceilf (spc * .75 * .2); CairoSetSouerceRGBA(c_wht); cairo_set_line_width (cr, 1); cairo_move_to (cr, xpr + mid, y0 + mid - span); cairo_line_to (cr, xpr + mid, y0 + mid + span); cairo_stroke (cr); cairo_move_to (cr, xpr + mid - span, y0 + mid); cairo_line_to (cr, xpr + mid + span, y0 + mid); cairo_stroke (cr); // mantissa for (int k = 0; k < 23; ++k) { const float xp = x0r - rintf (spc * (.5 * (k / 8) + k)); draw_bit_box (ui, cr, xp, y0, rad, -1, ui->flt[k + BIM_DSET]); } // magnitude for (int k = 0; k < 40; ++k) { const int o = k + 118; const float xp = .5 * (k / 8) + k; draw_bit_box (ui, cr, x0r_s - rintf (xp * spc_s), y0_s, rad_s, ui->flt[o + BIM_DHIT], ui->flt[o + BIM_DONE]); } if (ui->integration_spl == 0) { cairo_set_source_rgba (cr, 0, 0, 0, .6); cairo_rectangle (cr, 0, 0, ww, hh); cairo_fill (cr); write_text_full (cr, "<markup><b>No data available.</b></markup>", FONT(FONT_S), rintf(ww * .5f), rintf(hh * .5f), 0, 2, c_wht); } else if (ui->integration_spl >= 2147483647) { cairo_set_source_rgba (cr, .9, .9, .9, .5); cairo_rectangle (cr, 0, 0, ww, hh); cairo_fill (cr); write_text_full (cr, "<markup>Reached <b>2<sup><small>31</small></sup> sample limit.\nData acquisition suspended.</b></markup>", FONT(FONT_S), rintf(ww * .5f), rintf(hh * .5f), 0, 2, c_blk); } else if ((int)ui->integration_spl == ui->f_zero) { // all blank write_text_full (cr, "<markup><b>All samples are zero.</b></markup>", FONT(FONT_S), rintf(ww * .5f), rintf(y0_g + yh_g * .5f), 0, 2, c_wht); } return TRUE; }
static gboolean draw (ClutterCanvas *canvas, cairo_t *cr, int width_raw, int height_raw) { /* rounded rectangle taken from: * * http://cairographics.org/samples/rounded_rectangle/ * * we leave 1 pixel around the edges to avoid jagged edges * when rotating the actor */ double x = 1.0, /* parameters like cairo_rectangle */ y = 1.0, width = width_raw - 2.0, height = height_raw - 2.0, corner_radius = 5.0, tab_radius = 20.0; double radius = corner_radius ; double degrees = M_PI / 180.0; cairo_pattern_t *gradient; cairo_surface_t *image; cairo_pattern_t *imagelol; cairo_surface_t *image2; cairo_pattern_t *imagelol2; cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_restore (cr); cairo_new_sub_path (cr); cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees); cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees); /*bottom-left*/cairo_arc (cr, x + radius + 30, y + height - radius, radius, 90 * degrees, 180 * degrees); cairo_arc_negative (cr, x + 30 - tab_radius, 225, tab_radius, 0 * degrees, -45 * degrees); cairo_arc (cr, x + tab_radius, 255 - 75, tab_radius, 135 * degrees, 180 * degrees); cairo_arc (cr, x + tab_radius, 255 - 75 - 85, tab_radius, 180 * degrees, 225 * degrees); cairo_arc_negative (cr, x + 30 - tab_radius, 255 - 75 - 85 - 45, tab_radius, 45 * degrees, 0 * degrees); /*top-left*/cairo_arc (cr, x + radius + 30, y + radius, radius, 180 * degrees, 270 * degrees); cairo_close_path (cr); cairo_set_source_rgba (cr, 0.145098*1.7, 0.317647*1.6, 0.380392*1.5, 0.6); cairo_fill_preserve (cr); gradient = cairo_pattern_create_linear(0.0, 0.0, 0.0, 60); cairo_pattern_add_color_stop_rgba(gradient, 1, 0, 0, 0, 0); cairo_pattern_add_color_stop_rgba(gradient, 0, 1*.7, 1*.9, 1, .15); cairo_set_source(cr, gradient); cairo_fill_preserve(cr); gradient = cairo_pattern_create_linear(0.0, 0.0, 50.0, 0.0); cairo_pattern_add_color_stop_rgba(gradient, 1, 0, 0, 0, 0); cairo_pattern_add_color_stop_rgba(gradient, 0, 1*.7, 1*.9, 1, .08); cairo_set_source(cr, gradient); cairo_fill_preserve(cr); /*image = cairo_image_surface_create_from_png("/home/jason/workspace/lol/src/noise.png"); imagelol = cairo_pattern_create_for_surface(image); cairo_set_source(cr, imagelol); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_clip(cr); cairo_paint_with_alpha(cr, .1);*/ /* image2 = cairo_image_surface_create_from_png("/home/jason/Desktop/lol.png"); imagelol2 = cairo_pattern_create_for_surface(image2); cairo_set_source(cr, imagelol2); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_paint_with_alpha(cr, .25); *//* we're done drawing */ return TRUE; }
static void on_draw (GtkDrawingArea *darea, cairo_t *cr, int width, int height, gpointer data) { cairo_surface_t *overlay, *punch, *circles; cairo_t *overlay_cr, *punch_cr, *circles_cr; /* Fill the background */ double radius = 0.5 * (width < height ? width : height) - 10; double xc = width / 2.; double yc = height / 2.; overlay = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, width, height); punch = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_ALPHA, width, height); circles = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, width, height); fill_checks (cr, 0, 0, width, height); /* Draw a black circle on the overlay */ overlay_cr = cairo_create (overlay); cairo_set_source_rgb (overlay_cr, 0., 0., 0.); oval_path (overlay_cr, xc, yc, radius, radius); cairo_fill (overlay_cr); /* Draw 3 circles to the punch surface, then cut * that out of the main circle in the overlay */ punch_cr = cairo_create (punch); draw_3circles (punch_cr, xc, yc, radius, 1.0); cairo_destroy (punch_cr); cairo_set_operator (overlay_cr, CAIRO_OPERATOR_DEST_OUT); cairo_set_source_surface (overlay_cr, punch, 0, 0); cairo_paint (overlay_cr); /* Now draw the 3 circles in a subgroup again * at half intensity, and use OperatorAdd to join up * without seams. */ circles_cr = cairo_create (circles); cairo_set_operator (circles_cr, CAIRO_OPERATOR_OVER); draw_3circles (circles_cr, xc, yc, radius, 0.5); cairo_destroy (circles_cr); cairo_set_operator (overlay_cr, CAIRO_OPERATOR_ADD); cairo_set_source_surface (overlay_cr, circles, 0, 0); cairo_paint (overlay_cr); cairo_destroy (overlay_cr); cairo_set_source_surface (cr, overlay, 0, 0); cairo_paint (cr); cairo_surface_destroy (overlay); cairo_surface_destroy (punch); cairo_surface_destroy (circles); }
void lime_cairo_set_operator (value handle, int op) { cairo_set_operator ((cairo_t*)val_data (handle), (cairo_operator_t)op); }
void DrawResizableBackground(cairo_t *c, cairo_surface_t *background, int height, int width, int marginLeft, int marginTop, int marginRight, int marginBottom, FillRule fillV, FillRule fillH ) { int resizeHeight = cairo_image_surface_get_height(background) - marginTop - marginBottom; int resizeWidth = cairo_image_surface_get_width(background) - marginLeft - marginRight; if (resizeHeight <= 0) resizeHeight = 1; if (resizeWidth <= 0) resizeWidth = 1; cairo_save(c); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(c, background, 0, 0); /* 九宫格 * 7 8 9 * 4 5 6 * 1 2 3 */ /* part 1 */ cairo_save(c); cairo_translate(c, 0, height - marginBottom); cairo_set_source_surface(c, background, 0, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, marginLeft, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 3 */ cairo_save(c); cairo_translate(c, width - marginRight, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, marginRight, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 7 */ cairo_save(c); cairo_rectangle(c, 0, 0, marginLeft, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 9 */ cairo_save(c); cairo_translate(c, width - marginRight, 0); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, 0); cairo_rectangle(c, 0, 0, marginRight, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 & 8 */ { if (fillH == F_COPY) { int repaint_times = (width - marginLeft - marginRight) / resizeWidth; int remain_width = (width - marginLeft - marginRight) % resizeWidth; int i = 0; for (i = 0; i < repaint_times; i++) { /* part 8 */ cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth, 0); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, resizeWidth, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, resizeWidth, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } if (remain_width != 0) { /* part 8 */ cairo_save(c); cairo_translate(c, marginLeft + repaint_times * resizeWidth, 0); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, remain_width, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, marginLeft + repaint_times * resizeWidth, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, remain_width, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } else { cairo_save(c); cairo_translate(c, marginLeft, 0); cairo_scale(c, (double)(width - marginLeft - marginRight) / (double)resizeWidth, 1); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, resizeWidth, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_save(c); cairo_translate(c, marginLeft, height - marginBottom); cairo_scale(c, (double)(width - marginLeft - marginRight) / (double)resizeWidth, 1); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, resizeWidth, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } /* part 4 & 6 */ { if (fillV == F_COPY) { int repaint_times = (height - marginTop - marginBottom) / resizeHeight; int remain_height = (height - marginTop - marginBottom) % resizeHeight; int i = 0; for (i = 0; i < repaint_times; i++) { /* part 4 */ cairo_save(c); cairo_translate(c, 0, marginTop + i * resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 6 */ cairo_save(c); cairo_translate(c, width - marginRight, marginTop + i * resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); } if (remain_height != 0) { /* part 8 */ cairo_save(c); cairo_translate(c, 0, marginTop + repaint_times * resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, remain_height); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, width - marginRight, marginTop + repaint_times * resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, remain_height); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } else { cairo_save(c); cairo_translate(c, 0, marginTop); cairo_scale(c, 1, (double)(height - marginTop - marginBottom) / (double)resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_save(c); cairo_translate(c, width - marginRight, marginTop); cairo_scale(c, 1, (double)(height - marginTop - marginBottom) / (double)resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } /* part 5 */ { int repaintH = 0, repaintV = 0; int remainW = 0, remainH = 0; double scaleX = 1.0, scaleY = 1.0; if (fillH == F_COPY) { repaintH = (width - marginLeft - marginRight) / resizeWidth + 1; remainW = (width - marginLeft - marginRight) % resizeWidth; } else { repaintH = 1; scaleX = (double)(width - marginLeft - marginRight) / (double)resizeWidth; } if (fillV == F_COPY) { repaintV = (height - marginTop - marginBottom) / (double)resizeHeight + 1; remainH = (height - marginTop - marginBottom) % resizeHeight; } else { repaintV = 1; scaleY = (double)(height - marginTop - marginBottom) / (double)resizeHeight; } int i, j; for (i = 0; i < repaintH; i ++) { for (j = 0; j < repaintV; j ++) { cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth , marginTop + j * resizeHeight); cairo_scale(c, scaleX, scaleY); cairo_set_source_surface(c, background, -marginLeft, -marginTop); int w = resizeWidth, h = resizeHeight; if (fillV == F_COPY && j == repaintV - 1) h = remainH; if (fillH == F_COPY && i == repaintH - 1) w = remainW; cairo_rectangle(c, 0, 0, w, h); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } } cairo_restore(c); }
TGUIFont *Alloc_GUIFont(const char *AFontName, float AHeight) { TGUIFont *BFont = (TGUIFont *)malloc(sizeof(TGUIFont)); BFont->FGridWidth = 0; BFont->FGridHeight = 0; BFont->FHeight = AHeight; BFont->FExtents = (TGUIFontExtent *)malloc(sizeof(TGUIFontExtent) * 256); TGUIFontExtent *BCharExtent = BFont->FExtents; cairo_text_extents_t *BExtents = (cairo_text_extents_t *)malloc(sizeof(cairo_text_extents_t)); int BRow = 0; int BColumn = 0; GUIFont_GetGreaterSize(AFontName, AHeight, &BFont->FGridWidth, &BFont->FGridHeight); printf("[MESSAGE] Font grid of size (%i, %i).\n", BFont->FGridWidth, BFont->FGridHeight); BFont->FTextureWidth = Get_NextP2(BFont->FGridWidth * 16); BFont->FTextureHeight = Get_NextP2(BFont->FGridHeight * 16); printf("[MESSAGE] Font texture of size (%i, %i).\n", BFont->FTextureWidth, BFont->FTextureHeight); unsigned char *BData = NULL; unsigned char *BText = (unsigned char *)malloc(sizeof(unsigned char) * 2); BText[0] = 0; BText[1] = '\0'; // Create texture data . cairo_surface_t *BSurface = cairo_image_surface_create(CAIRO_FORMAT_A8, BFont->FTextureWidth, BFont->FTextureHeight); cairo_t *BContext = cairo_create(BSurface); cairo_set_antialias(BContext, CAIRO_ANTIALIAS_NONE); cairo_set_operator(BContext, CAIRO_OPERATOR_OVER); cairo_set_source_rgba(BContext, 0.0, 0.0, 0.0, 0.0); cairo_font_options_t *cfo = cairo_font_options_create(); cairo_font_options_set_antialias(cfo, CAIRO_ANTIALIAS_SUBPIXEL); cairo_set_font_options(BContext, cfo); cairo_set_source_rgba(BContext, 0.0, 0.0, 0.0, 1.0); cairo_select_font_face(BContext, AFontName, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(BContext, AHeight); for (BText[0] = 0; BText[0] < 255; BText[0]++) { cairo_text_extents(BContext, BText, BExtents); if (BExtents) { BCharExtent->FAdvanceX = BExtents->x_advance; if (BText[0] == 32) { //BCharExtent->FAdvanceX = BFont->FGridWidth; }; BCharExtent->FAdvanceY = BExtents->y_advance; BCharExtent->FBearingX = BExtents->x_bearing; BCharExtent->FBearingY = BExtents->y_bearing; BCharExtent->FWidth = BExtents->width; BCharExtent->FHeight = BExtents->height; BRow = BText[0] / 16; BColumn = BText[0] % 16; cairo_move_to(BContext, -BExtents->x_bearing + (BColumn * BFont->FGridWidth), -BExtents->y_bearing + (BRow * BFont->FGridHeight)); cairo_show_text(BContext, BText); } else { printf("[MESSAGE] Fail to create font. Extents of char %i returned as null.\n", BText[0]); return NULL; }; BCharExtent++; }; cairo_surface_flush(BSurface); //cairo_surface_write_to_png(BSurface, "/home/felipefs/Desktop/texture.png"); BData = cairo_image_surface_get_data(BSurface); glGenTextures(1, &BFont->FTexture); glBindTexture(GL_TEXTURE_2D, BFont->FTexture); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BFont->FTextureWidth, BFont->FTextureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, BData); cairo_destroy(BContext); cairo_surface_destroy(BSurface); //free(BData); if (glIsTexture(BFont->FTexture) == GL_FALSE) { printf("[ERROR] Fail to create character texture of size %ix%i.\n", BFont->FTextureWidth, BFont->FTextureHeight); }; printf("[MESSAGE] Font created.\n"); return BFont; };
bool CurveGradient::accelerated_cairorender(Context context, cairo_t *cr,int quality, const RendDesc &renddesc_, ProgressCallback *cb)const { RendDesc renddesc(renddesc_); // Untransform the render desc if(!cairo_renddesc_untransform(cr, renddesc)) return false; Point pos; const Real pw(renddesc.get_pw()),ph(renddesc.get_ph()); const Point tl(renddesc.get_tl()); const int w(renddesc.get_w()); const int h(renddesc.get_h()); SuperCallback supercb(cb,0,9500,10000); if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT) { cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_restore(cr); } else { if(!context.accelerated_cairorender(cr,quality,renddesc,&supercb)) return false; if(get_amount()==0) return true; } int x,y; cairo_surface_t *surface; surface=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, w, h); CairoSurface csurface(surface); if(!csurface.map_cairo_image()) { synfig::warning("Curve Gradient: map cairo surface failed"); return false; } for(y=0,pos[1]=tl[1]; y<h; y++,pos[1]+=ph) for(x=0,pos[0]=tl[0]; x<w; x++,pos[0]+=pw) csurface[y][x]=CairoColor(color_func(pos,calc_supersample(pos,pw,ph))).premult_alpha(); csurface.unmap_cairo_image(); // paint surface on cr cairo_save(cr); cairo_translate(cr, tl[0], tl[1]); cairo_scale(cr, pw, ph); cairo_set_source_surface(cr, surface, 0, 0); cairo_paint_with_alpha_operator(cr, get_amount(), get_blend_method()); cairo_restore(cr); cairo_surface_destroy(surface); // Mark our progress as finished if(cb && !cb->amount_complete(10000,10000)) return false; return true; }
void PluginView::paint(GraphicsContext* context, const IntRect& rect) { if (!m_isStarted || m_status != PluginStatusLoadedSuccessfully) { paintMissingPluginIcon(context, rect); return; } if (context->paintingDisabled()) return; setNPWindowIfNeeded(); if (m_isWindowed) return; if (!m_drawable) return; Display* display = getPluginDisplay(nullptr); const bool syncX = m_pluginDisplay && m_pluginDisplay != display; IntRect exposedRect(rect); exposedRect.intersect(frameRect()); exposedRect.move(-frameRect().x(), -frameRect().y()); RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(display, m_drawable, m_visual, m_windowRect.width(), m_windowRect.height())); if (m_isTransparent) { // If we have a 32 bit drawable and the plugin wants transparency, // we'll clear the exposed area to transparent first. Otherwise, // we'd end up with junk in there from the last paint, or, worse, // uninitialized data. RefPtr<cairo_t> cr = adoptRef(cairo_create(drawableSurface.get())); if (!(cairo_surface_get_content(drawableSurface.get()) & CAIRO_CONTENT_ALPHA)) { // Attempt to fake it when we don't have an alpha channel on our // pixmap. If that's not possible, at least clear the window to // avoid drawing artifacts. // This Would not work without double buffering, but we always use it. cairo_set_source_surface(cr.get(), cairo_get_group_target(context->platformContext()->cr()), -m_windowRect.x(), -m_windowRect.y()); cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE); } else cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr.get(), exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height()); cairo_fill(cr.get()); } XEvent xevent; memset(&xevent, 0, sizeof(XEvent)); XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; exposeEvent.type = GraphicsExpose; exposeEvent.display = display; exposeEvent.drawable = m_drawable; exposeEvent.x = exposedRect.x(); exposeEvent.y = exposedRect.y(); exposeEvent.width = exposedRect.x() + exposedRect.width(); // flash bug? it thinks width is the right in transparent mode exposeEvent.height = exposedRect.y() + exposedRect.height(); // flash bug? it thinks height is the bottom in transparent mode dispatchNPEvent(xevent); if (syncX) XSync(m_pluginDisplay, false); // sync changes by plugin cairo_t* cr = context->platformContext()->cr(); cairo_save(cr); cairo_set_source_surface(cr, drawableSurface.get(), frameRect().x(), frameRect().y()); cairo_rectangle(cr, frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y(), exposedRect.width(), exposedRect.height()); cairo_clip(cr); if (m_isTransparent) cairo_set_operator(cr, CAIRO_OPERATOR_OVER); else cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); }
/** * Create a thumbnail of a page. * * \param content content structure to thumbnail * \param bitmap the bitmap to draw to * \param url the URL the thumnail belongs to, or NULL */ bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap, const char *url) { cairo_surface_t *dsurface = bitmap->surface; cairo_surface_t *surface; cairo_t *old_cr; gint dwidth, dheight; int cwidth, cheight; struct redraw_context ctx = { .interactive = false, .background_images = true, .plot = &nsgtk_plotters }; assert(content); assert(bitmap); dwidth = cairo_image_surface_get_width(dsurface); dheight = cairo_image_surface_get_height(dsurface); /* Calculate size of buffer to render the content into */ /* We get the width from the content width, unless it exceeds 1024, * in which case we use 1024. This means we never create excessively * large render buffers for huge contents, which would eat memory and * cripple performance. */ cwidth = min(content_get_width(content), 1024); /* The height is set in proportion with the width, according to the * aspect ratio of the required thumbnail. */ cheight = ((cwidth * dheight) + (dwidth / 2)) / dwidth; /* Create surface to render into */ surface = cairo_surface_create_similar(dsurface, CAIRO_CONTENT_COLOR_ALPHA, cwidth, cheight); if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy(surface); return false; } old_cr = current_cr; current_cr = cairo_create(surface); /* render the content */ thumbnail_redraw(content, cwidth, cheight, &ctx); cairo_destroy(current_cr); current_cr = old_cr; cairo_t *cr = cairo_create(dsurface); /* Scale *before* setting the source surface (1) */ cairo_scale (cr, (double)dwidth / cwidth, (double)dheight / cheight); cairo_set_source_surface (cr, surface, 0, 0); /* To avoid getting the edge pixels blended with 0 alpha, * which would occur with the default EXTEND_NONE. Use * EXTEND_PAD for 1.2 or newer (2) */ cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT); /* Replace the destination with the source instead of overlaying */ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); /* Do the actual drawing */ cairo_paint(cr); cairo_destroy(cr); cairo_surface_destroy(surface); /* register the thumbnail with the URL */ if (url) urldb_set_thumbnail(url, bitmap); return true; }
void ShowInfo(char *pchText, char *pchText2, HWND hwndClientWindow, cairo_surface_t *pCairoSurface, cairo_t *pCairoHandle) { cairo_text_extents_t CairoTextExtents; cairo_text_extents_t CairoTextExtents2; cairo_pattern_t *pattern1; cairo_set_operator(pCairoHandle, CAIRO_OPERATOR_OVER); // Set random line width cairo_set_line_width(pCairoHandle, 0.03); cairo_select_font_face(pCairoHandle, "Sans", 0, 0); cairo_set_font_size(pCairoHandle, 0.05); // Get how big the text will be! cairo_text_extents(pCairoHandle, pchText, &CairoTextExtents); cairo_text_extents(pCairoHandle, pchText2, &CairoTextExtents2); // Draw a frame pattern1 = cairo_pattern_create_linear(0.3,0,0.7,1); cairo_pattern_add_color_stop_rgba(pattern1, 0, 0, 0, 0, 1); cairo_pattern_add_color_stop_rgba(pattern1, 0.5, 0, 0.5, 0, 1); cairo_pattern_add_color_stop_rgba(pattern1, 1, 0.3, 1, 0.2, 1); //cairo_set_source_rgba(pCairoHandle, 0.2, 0.8 ,0, 0.9); cairo_set_source(pCairoHandle, pattern1); cairo_rectangle(pCairoHandle, 0.05 * dXAspect, 0.25*dYAspect, 0.90 * dXAspect, 0.5*dYAspect); cairo_fill_preserve(pCairoHandle); cairo_set_source_rgba(pCairoHandle, 0.9, 0.5, 0.2, 0.7); cairo_stroke(pCairoHandle); cairo_pattern_destroy(pattern1); pattern1 = cairo_pattern_create_linear(0,0,1,1); cairo_pattern_add_color_stop_rgba(pattern1, 0, 0.1, 0.7, 0.3, 0.4); cairo_pattern_add_color_stop_rgba(pattern1, 0.2, 0.3, 0.2, 0.4, 0.6); cairo_pattern_add_color_stop_rgba(pattern1, 0.4, 0.1, 0.1, 0.8, 0.3); cairo_pattern_add_color_stop_rgba(pattern1, 0.6, 0, 0.5, 0.7, 0.4); cairo_pattern_add_color_stop_rgba(pattern1, 0.8, 0.4, 0.5, 0.2, 0.6); cairo_pattern_add_color_stop_rgba(pattern1, 1, 0.1, 1, 0.2, 0.3); //cairo_set_source_rgba(pCairoHandle, 0.2, 0.8 ,0, 0.9); cairo_set_source(pCairoHandle, pattern1); cairo_rectangle(pCairoHandle, 0.05 * dXAspect, 0.25*dYAspect, 0.90 * dXAspect, 0.5*dYAspect); cairo_fill(pCairoHandle); cairo_pattern_destroy(pattern1); // Print the text, centered! cairo_set_source_rgba(pCairoHandle, 1, 1, 1, 0.8); cairo_move_to(pCairoHandle, (0.5*dXAspect - CairoTextExtents.width/2), (0.5*dYAspect - CairoTextExtents.height)); cairo_show_text(pCairoHandle, pchText); cairo_stroke (pCairoHandle); // Print the text, centered! cairo_move_to(pCairoHandle, 0.1 * dXAspect, (0.5*dYAspect + CairoTextExtents2.height)); cairo_scale(pCairoHandle, 0.8*dXAspect/CairoTextExtents2.width, 1); cairo_show_text(pCairoHandle, pchText2); cairo_stroke (pCairoHandle); }