// "cairo in motion" is a testbed for animated vector-drawing // using cairo within a gtk+-environment // // Copyright (C) 2005 Mirco Mueller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include #include "cairo-samples.h" CairoSamples::CairoSamples () { // initialize animation-variables m_center.x = 0.5f; m_center.y = 0.5f; m_point1.x = 0.1f; m_point1.y = 0.2f; m_point2.x = 0.5f; m_point2.y = 0.5f; m_point3.x = 0.8f; m_point3.y = 0.4f; m_point4.x = 0.2f; m_point4.y = 0.9f; m_fRadius = 0.25f; m_fAngle1 = 0.0f; m_fAngle2 = 360.0f; m_centerXStep = 0.0025f; m_centerYStep = 0.0025f; m_point1XStep = -0.0025f; m_point1YStep = -0.0025f; m_point2XStep = 0.0025f; m_point2YStep = -0.0025f; m_point2XStep = 0.0025f; m_point3YStep = -0.0025f; m_point4XStep = 0.0025f; m_point4YStep = -0.0025f; m_fRadiusStep = 0.0025f; m_fAngle1Step = 0.5f; m_fAngle2Step = -1.5f; // setup sample-entry list Entry* pEntry = new Entry; pEntry->name = "curve_rectangle"; m_sampleList.push_back (*pEntry); pEntry->name = "fill_and_stroke"; m_sampleList.push_back (*pEntry); pEntry->name = "fill_and_stroke2"; m_sampleList.push_back (*pEntry); pEntry->name = "fontmania"; m_sampleList.push_back (*pEntry); pEntry->name = "gradient"; m_sampleList.push_back (*pEntry); pEntry->name = "image"; m_sampleList.push_back (*pEntry); pEntry->name = "image_pattern"; m_sampleList.push_back (*pEntry); pEntry->name = "libsvg"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_arc"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_arc_negative"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_cairo_logo"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_clip"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_clip_image"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_curve_to"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_gradient"; m_sampleList.push_back (*pEntry); pEntry->name = "moving_gradient2"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_add"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_atop"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_atop_reverse"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_in"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_in_reverse"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_out"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_out_reverse"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_over"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_over_reverse"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_saturate"; m_sampleList.push_back (*pEntry); pEntry->name = "operator_xor"; m_sampleList.push_back (*pEntry); pEntry->name = "path"; m_sampleList.push_back (*pEntry); pEntry->name = "pattern_fill"; m_sampleList.push_back (*pEntry); pEntry->name = "set_line_cap"; m_sampleList.push_back (*pEntry); pEntry->name = "set_line_join"; m_sampleList.push_back (*pEntry); pEntry->name = "text_align_center"; m_sampleList.push_back (*pEntry); pEntry->name = "text"; m_sampleList.push_back (*pEntry); pEntry->name = "text_extents"; m_sampleList.push_back (*pEntry); pEntry->name = "xxx_clip_rectangle"; m_sampleList.push_back (*pEntry); pEntry->name = "xxx_dash"; m_sampleList.push_back (*pEntry); pEntry->name = "xxx_long_lines"; m_sampleList.push_back (*pEntry); pEntry->name = "xxx_multi_segment_caps"; m_sampleList.push_back (*pEntry); pEntry->name = "xxx_self_intersect"; m_sampleList.push_back (*pEntry); } CairoSamples::~CairoSamples () { } void CairoSamples::do_animation_step () { srand (42); // update vars update_var (&m_center.x, 0.0f, 1.0f, &m_centerXStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_center.y, 0.0f, 1.0f, &m_centerYStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point1.x, 0.0f, 1.0f, &m_point1XStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point1.y, 0.0f, 1.0f, &m_point1YStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point2.x, 0.0f, 1.0f, &m_point2XStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point2.y, 0.0f, 1.0f, &m_point2YStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point3.x, 0.0f, 1.0f, &m_point3XStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point3.y, 0.0f, 1.0f, &m_point3YStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point4.x, 0.0f, 1.0f, &m_point4XStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_point4.y, 0.0f, 1.0f, &m_point4YStep, (double) rand() * 0.025 / RAND_MAX, (double) rand() * -0.025 / RAND_MAX); update_var (&m_fRadius, 0.05f, 0.5f, &m_fRadiusStep, (double) rand() * 0.0125 / RAND_MAX, (double) rand() * -0.0125 / RAND_MAX); update_var (&m_fAngle1, 0.0f, 360.0f, &m_fAngle1Step, 0.5f, -1.0f); update_var (&m_fAngle2, 0.0f, 360.0f, &m_fAngle2Step, 2.0f, -0.75f); } void CairoSamples::set_context (cairo_t* pCairoContext) { m_pCairoContext = pCairoContext; } void CairoSamples::normalize_canvas (double fWidth, double fHeight) const { cairo_scale (m_pCairoContext, fWidth, fHeight); } void CairoSamples::set_bg_svg (std::string strSVGFileName) const { unsigned int uiWidth; unsigned int uiHeight; svg_cairo_t* pSVGContext; svg_cairo_create (&pSVGContext); svg_cairo_parse (pSVGContext, strSVGFileName.c_str ()); svg_cairo_get_size (pSVGContext, &uiWidth, &uiHeight); cairo_save (m_pCairoContext); cairo_scale (m_pCairoContext, 1.0f / uiWidth, 1.0f / uiHeight); svg_cairo_render (pSVGContext, m_pCairoContext); cairo_restore (m_pCairoContext); svg_cairo_destroy (pSVGContext); } bool CairoSamples::do_sample (Sample sample) const { bool bResult = false; switch (sample) { case CurveRectangle : bResult = curve_rectangle (); break; case FillAndStroke : bResult = fill_and_stroke (); break; case FillAndStroke2 : bResult = fill_and_stroke2 (); break; case Fontmania : bResult = fontmania (); break; case Gradient : bResult = gradient (); break; case Image : bResult = image (); break; case ImagePattern : bResult = image_pattern (); break; case LibSVG : bResult = libsvg (); break; case MovingArc : bResult = moving_arc (); break; case MovingArcNegative : bResult = moving_arc_negative (); break; case MovingCairoLogo : bResult = moving_cairo_logo (); break; case MovingClip : bResult = moving_clip (); break; case MovingClipImage : bResult = moving_clip_image (); break; case MovingCurveTo : bResult = moving_curve_to (); break; case MovingGradient : bResult = moving_gradient (); break; case MovingGradient2 : bResult = moving_gradient2 (); break; case OperatorAdd : bResult = operator_add (); break; case OperatorAtop : bResult = operator_atop (); break; case OperatorAtopReverse : bResult = operator_atop_reverse (); break; case OperatorIn : bResult = operator_in (); break; case OperatorInReverse : bResult = operator_in_reverse (); break; case OperatorOut : bResult = operator_out (); break; case OperatorOutReverse : bResult = operator_out_reverse (); break; case OperatorOver : bResult = operator_over (); break; case OperatorOverReverse : bResult = operator_over_reverse (); break; case OperatorSaturate : bResult = operator_saturate (); break; case OperatorXor : bResult = operator_xor (); break; case Path : bResult = path (); break; case PatternFill : bResult = pattern_fill (); break; case SetLineCap : bResult = set_line_cap (); break; case SetLineJoin : bResult = set_line_join (); break; case TextAlignCenter : bResult = text_align_center (); break; case Text : bResult = text (); break; case TextExtents : bResult = text_extents (); break; case XxxClipRectangle : bResult = xxx_clip_rectangle (); break; case XxxDash : bResult = xxx_dash (); break; case XxxLongLines : bResult = xxx_long_lines (); break; case XxxMultiSegmentCaps : bResult = xxx_multi_segment_caps (); break; case XxxSelfIntersect : bResult = xxx_self_intersect (); break; default : bResult = sample_not_found (); break; } return bResult; } void CairoSamples::set_cap_style (cairo_line_cap_t cairoCapStyle) { m_cairoCapStyle = cairoCapStyle; } void CairoSamples::set_join_style (cairo_line_join_t cairoJoinStyle) { m_cairoJoinStyle = cairoJoinStyle; } void CairoSamples::set_dash_style (DashStyle dashStyle) { m_dashStyle = dashStyle; } void CairoSamples::set_operator (cairo_operator_t cairoOperator) { m_cairoOperator = cairoOperator; } void CairoSamples::set_extend_mode (cairo_extend_t cairoExtendMode) { m_cairoExtendMode = cairoExtendMode; } void CairoSamples::set_filter_mode (cairo_filter_t cairoFilterMode) { m_cairoFilterMode = cairoFilterMode; } void CairoSamples::set_line_width (double fLineWidth) { m_fLineWidth = fLineWidth; } void CairoSamples::set_bg_color (Gdk::Color bgColor) { m_bgColor = bgColor; } void CairoSamples::set_font_family (std::string strFontFamily) { m_strFontFamily = strFontFamily; } void CairoSamples::set_font_size (double fFontSize) { m_fFontSize = fFontSize; } void CairoSamples::set_font_weight (cairo_font_weight_t cairoFontWeight) { m_cairoFontWeight = cairoFontWeight; } void CairoSamples::set_font_slant (cairo_font_slant_t cairoFontSlant) { m_cairoFontSlant = cairoFontSlant; } void CairoSamples::set_some_text (std::string strSomeText) { m_strSomeText = strSomeText; } void CairoSamples::set_image_file_name (std::string strFileName) { m_strImageFileName = strFileName; } void CairoSamples::set_svg_file_name (std::string strFileName) { m_strSvgFileName = strFileName; } void CairoSamples::add_samples_to_list_store (SampleListStore* pSampleListStore) { if (!pSampleListStore) return; for (std::vector::iterator iter = m_sampleList.begin (); iter != m_sampleList.end (); iter++) { pSampleListStore->add_item ((*iter).name); } } std::string CairoSamples::get_sample_name (Sample sample) const { return m_sampleList[sample].name; } void CairoSamples::update_var (double* pfValue, double fLowerLimit, double fUpperLimit, double* pfStep, double fGrow, double fShrink) { if (*pfValue <= fLowerLimit) { *pfValue = fLowerLimit; *pfStep = fGrow; } if (*pfValue >= fUpperLimit) { *pfValue = fUpperLimit; *pfStep = fShrink; } *pfValue += *pfStep; } HandlePoint CairoSamples::get_center () const { return m_center; } HandlePoint CairoSamples::get_point1 () const { return m_point1; } HandlePoint CairoSamples::get_point2 () const { return m_point2; } HandlePoint CairoSamples::get_point3 () const { return m_point3; } HandlePoint CairoSamples::get_point4 () const { return m_point4; } double CairoSamples::get_radius () const { return m_fRadius; } double CairoSamples::get_angle_1 () const { return m_fAngle1; } double CairoSamples::get_angle_2 () const { return m_fAngle2; } void CairoSamples::draw_background () const { int iX; int iY; bool bToggle = false; for (iX = 0; iX < 20; iX++) { bToggle = !bToggle; for (iY = 0; iY < 20; iY++) { if (bToggle) { cairo_set_source_rgb (m_pCairoContext, m_bgColor.get_red_p (), m_bgColor.get_green_p (), m_bgColor.get_blue_p ()); bToggle = !bToggle; } else { cairo_set_source_rgb (m_pCairoContext, m_bgColor.get_red_p () - 0.1f, m_bgColor.get_green_p () - 0.1f, m_bgColor.get_blue_p () - 0.1f); bToggle = !bToggle; } cairo_rectangle (m_pCairoContext, iX * 0.05f, iY * 0.05f, 0.05f, 0.05f); cairo_fill (m_pCairoContext); } } } void CairoSamples::draw_background (Gdk::Color color) const { cairo_set_source_rgba (m_pCairoContext, color.get_red_p (), color.get_green_p (), color.get_blue_p (), 1.0f); cairo_rectangle (m_pCairoContext, 0.0f, 0.0f, 1.0f, 1.0f); cairo_fill (m_pCairoContext); } void CairoSamples::draw_handle (HandlePoint* pPoint) const { if (!pPoint) return; draw_handle (pPoint->x, pPoint->y); } void CairoSamples::draw_handle (double fX, double fY) const { double fRadius = 0.01f; if (!m_pCairoContext) return; cairo_set_dash (m_pCairoContext, NULL, 0, 0.0f); cairo_set_line_width (m_pCairoContext, 0.002f); cairo_set_line_cap (m_pCairoContext, CAIRO_LINE_CAP_BUTT); cairo_set_line_join (m_pCairoContext, CAIRO_LINE_JOIN_ROUND); /* draw white/green-ish outline */ cairo_set_source_rgb (m_pCairoContext, 0.9f, 1.0f, 0.8f); cairo_arc (m_pCairoContext, fX, fY, fRadius, 0.0f, 2.0f * M_PI); cairo_stroke (m_pCairoContext); /* draw grey/transparent center */ cairo_set_source_rgba (m_pCairoContext, 0.6f, 0.6f, 0.6f, 0.5f); cairo_arc (m_pCairoContext, fX, fY, fRadius, 0.0f, 2.0f * M_PI); cairo_fill (m_pCairoContext); } bool CairoSamples::sample_not_found () const { if (!m_pCairoContext) return false; cairo_select_font_face (m_pCairoContext, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (m_pCairoContext, 0.115f); Gdk::Color white ("#ffffff"); draw_background (white); cairo_set_source_rgb (m_pCairoContext, 1.0f, 0.0f, 0.0f); cairo_move_to (m_pCairoContext, 0.04f, 0.53f); cairo_show_text (m_pCairoContext, "Sample not found!"); return true; } bool CairoSamples::curve_rectangle () const { if (!m_pCairoContext) return false; double x0 = 0.1f; double y0 = 0.1f; double rect_width = 0.8f; double rect_height = 0.8f; double radius = 0.4f; double x1; double y1; x1 = x0 + rect_width; y1 = y0 + rect_height; draw_background (); cairo_set_line_width (m_pCairoContext, m_fLineWidth); if (!rect_width || !rect_height) return false; if (rect_width / 2.0f < radius) { if (rect_height / 2.0f < radius) { cairo_move_to (m_pCairoContext, x0, (y0 + y1) / 2.0f); cairo_curve_to (m_pCairoContext, x0 ,y0, x0, y0, (x0 + x1) / 2.0f, y0); cairo_curve_to (m_pCairoContext, x1, y0, x1, y0, x1, (y0 + y1) / 2.0f); cairo_curve_to (m_pCairoContext, x1, y1, x1, y1, (x1 + x0) / 2.0f, y1); cairo_curve_to (m_pCairoContext, x0, y1, x0, y1, x0, (y0 + y1) / 2.0f); } else { cairo_move_to (m_pCairoContext, x0, y0 + radius); cairo_curve_to (m_pCairoContext, x0 ,y0, x0, y0, (x0 + x1) / 2.0f, y0); cairo_curve_to (m_pCairoContext, x1, y0, x1, y0, x1, y0 + radius); cairo_line_to (m_pCairoContext, x1 , y1 - radius); cairo_curve_to (m_pCairoContext, x1, y1, x1, y1, (x1 + x0) / 2.0f, y1); cairo_curve_to (m_pCairoContext, x0, y1, x0, y1, x0, y1- radius); } } else { if (rect_height / 2.0f < radius) { cairo_move_to (m_pCairoContext, x0, (y0 + y1) / 2.0f); cairo_curve_to (m_pCairoContext, x0 , y0, x0 , y0, x0 + radius, y0); cairo_line_to (m_pCairoContext, x1 - radius, y0); cairo_curve_to (m_pCairoContext, x1, y0, x1, y0, x1, (y0 + y1) / 2.0f); cairo_curve_to (m_pCairoContext, x1, y1, x1, y1, x1 - radius, y1); cairo_line_to (m_pCairoContext, x0 + radius, y1); cairo_curve_to (m_pCairoContext, x0, y1, x0, y1, x0, (y0 + y1) / 2.0f); } else { cairo_move_to (m_pCairoContext, x0, y0 + radius); cairo_curve_to (m_pCairoContext, x0 , y0, x0 , y0, x0 + radius, y0); cairo_line_to (m_pCairoContext, x1 - radius, y0); cairo_curve_to (m_pCairoContext, x1, y0, x1, y0, x1, y0 + radius); cairo_line_to (m_pCairoContext, x1 , y1 - radius); cairo_curve_to (m_pCairoContext, x1, y1, x1, y1, x1 - radius, y1); cairo_line_to (m_pCairoContext, x0 + radius, y1); cairo_curve_to (m_pCairoContext, x0, y1, x0, y1, x0, y1- radius); } } cairo_close_path (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.5f, 0.5f, 1.0f); cairo_fill_preserve (m_pCairoContext); cairo_set_source_rgba (m_pCairoContext, 0.5f, 0.0f, 0.0f, 0.5f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::fill_and_stroke () const { if (!m_pCairoContext) return false; draw_background (); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.5f, 0.1f); cairo_line_to (m_pCairoContext, 0.9f, 0.9f); cairo_rel_line_to (m_pCairoContext, -0.4f, 0.0f); cairo_curve_to (m_pCairoContext, 0.2f, 0.9f, 0.2f, 0.5f, 0.5f, 0.5f); cairo_close_path (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_fill_preserve (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::fill_and_stroke2 () const { if (!m_pCairoContext) return false; draw_background (); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.5f, 0.1f); cairo_line_to (m_pCairoContext, 0.9f, 0.9f); cairo_rel_line_to (m_pCairoContext, -0.4f, 0.0f); cairo_curve_to (m_pCairoContext, 0.2f, 0.9f, 0.2f, 0.5f, 0.5f, 0.5f); cairo_close_path (m_pCairoContext); cairo_move_to (m_pCairoContext, 0.25f, 0.1f); cairo_rel_line_to (m_pCairoContext, 0.2f, 0.2f); cairo_rel_line_to (m_pCairoContext, -0.2f, 0.2f); cairo_rel_line_to (m_pCairoContext, -0.2f, -0.2f); cairo_close_path (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_fill_preserve (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::fontmania () const { draw_background (); std::string theText = "Fontmania"; // set font-attributes cairo_select_font_face (m_pCairoContext, "Times New Roman", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (m_pCairoContext, 0.6f); // draw the solid black text cairo_set_source_rgba (m_pCairoContext, 0.0f, 0.0f, 0.0f, 0.15f); cairo_move_to (m_pCairoContext, 0.05f, 0.6f); cairo_show_text (m_pCairoContext, theText.c_str ()); // set font-attributes cairo_select_font_face (m_pCairoContext, "Arial Black", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (m_pCairoContext, 0.1f); // draw the solid black text cairo_set_source_rgba (m_pCairoContext, 0.0f, 0.0f, 0.0f, 1.0f); cairo_move_to (m_pCairoContext, 0.4f, 0.6f); cairo_show_text (m_pCairoContext, theText.c_str ()); // set font-attributes cairo_select_font_face (m_pCairoContext, "Verdana", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (m_pCairoContext, 0.15f); // draw the solid black text cairo_set_source_rgba (m_pCairoContext, 0.0f, 0.0f, 0.0f, 0.25f); cairo_move_to (m_pCairoContext, 0.1f, 0.6f); cairo_show_text (m_pCairoContext, theText.c_str ()); // set font-attributes cairo_select_font_face (m_pCairoContext, "Impact", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (m_pCairoContext, 0.2f); // draw the solid black text cairo_set_source_rgba (m_pCairoContext, 0.0f, 0.0f, 0.0f, 0.35f); cairo_move_to (m_pCairoContext, 0.3f, 0.6f); cairo_show_text (m_pCairoContext, theText.c_str ()); return true; } bool CairoSamples::gradient () const { if (!m_pCairoContext) return false; cairo_pattern_t* pPattern; pPattern = cairo_pattern_create_linear (0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (pPattern, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (pPattern, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.0f, 0.0f, 1.0f, 1.0f); cairo_set_source (m_pCairoContext, pPattern); cairo_fill (m_pCairoContext); cairo_pattern_destroy (pPattern); pPattern = cairo_pattern_create_radial (0.45f, 0.4f, 0.1f, 0.4f, 0.4f, 0.5f); cairo_pattern_add_color_stop_rgba (pPattern, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f); cairo_pattern_add_color_stop_rgba (pPattern, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_set_source (m_pCairoContext, pPattern); cairo_arc (m_pCairoContext, 0.5f, 0.5f, 0.3f, 0.0f, 2.0f * M_PI); cairo_fill (m_pCairoContext); cairo_pattern_destroy (pPattern); return true; } bool CairoSamples::image () const { if (!m_pCairoContext) return false; draw_background (); int iWidth; int iHeight; cairo_surface_t* pImage; pImage = cairo_image_surface_create_from_png (m_strImageFileName.c_str ()); iWidth = cairo_image_surface_get_width (pImage); iHeight = cairo_image_surface_get_height (pImage); cairo_translate (m_pCairoContext, 0.5f, 0.5f); cairo_rotate (m_pCairoContext, 45.0f * M_PI / 180.0f); cairo_scale (m_pCairoContext, 1.0f / iWidth, 1.0f / iHeight); cairo_translate (m_pCairoContext, -0.5f * iWidth, -0.5f * iHeight); cairo_set_source_surface (m_pCairoContext, pImage, 0.0f, 0.0f); cairo_paint (m_pCairoContext); cairo_surface_destroy (pImage); return true; } bool CairoSamples::image_pattern () const { if (!m_pCairoContext) return false; draw_background (); int iWidth; int iHeight; cairo_surface_t* pImage; cairo_pattern_t* pPattern; cairo_matrix_t matrix; pImage = cairo_image_surface_create_from_png (m_strImageFileName.c_str ()); iWidth = cairo_image_surface_get_width (pImage); iHeight = cairo_image_surface_get_height (pImage); pPattern = cairo_pattern_create_for_surface (pImage); cairo_pattern_set_extend (pPattern, m_cairoExtendMode); cairo_pattern_set_filter (pPattern, m_cairoFilterMode); cairo_translate (m_pCairoContext, 0.5f, 0.5f); cairo_rotate (m_pCairoContext, M_PI / 4.0f); cairo_scale (m_pCairoContext, 1.0f / sqrt (2.0f), 1.0f / sqrt (2.0f)); cairo_translate (m_pCairoContext, - 0.5f, - 0.5f); cairo_matrix_init_scale (&matrix, iWidth * 5.0f, iHeight * 5.0f); cairo_pattern_set_matrix (pPattern, &matrix); cairo_set_source (m_pCairoContext, pPattern); cairo_rectangle (m_pCairoContext, 0.0f, 0.0f, 1.0f, 1.0f); cairo_fill (m_pCairoContext); cairo_pattern_destroy (pPattern); cairo_surface_destroy (pImage); return true; } bool CairoSamples::libsvg () const { if (!m_pCairoContext) return false; draw_background (); svg_cairo_t* pSVGContext; unsigned int uiWidth; unsigned int uiHeight; svg_cairo_create (&pSVGContext); svg_cairo_parse (pSVGContext, m_strSvgFileName.c_str ()); svg_cairo_get_size (pSVGContext, &uiWidth, &uiHeight); cairo_scale (m_pCairoContext, 1.0f / uiWidth, 1.0f / uiHeight); svg_cairo_render (pSVGContext, m_pCairoContext); svg_cairo_destroy (pSVGContext); return true; } bool CairoSamples::moving_arc () const { if (!m_pCairoContext) return false; HandlePoint center = get_center (); double fRadius = get_radius (); double radiantAngle1 = get_angle_1 () * (M_PI/180.0); double radiantAngle2 = get_angle_2 () * (M_PI/180.0); HandlePoint firstHandle = { center.x + fRadius * cos (radiantAngle1), center.y + fRadius * sin (radiantAngle1) }; HandlePoint secondHandle = { center.x + fRadius * cos (radiantAngle2), center.y + fRadius * sin (radiantAngle2)}; draw_background (); // draw black arc cairo_set_line_width(m_pCairoContext, m_fLineWidth); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_arc (m_pCairoContext, center.x, center.y, fRadius, radiantAngle1, radiantAngle2); cairo_stroke (m_pCairoContext); // draw the two "helper"-lines cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_set_line_width (m_pCairoContext, 0.005f); cairo_move_to (m_pCairoContext, center.x, center.y); cairo_line_to (m_pCairoContext, firstHandle.x, firstHandle.y); cairo_move_to (m_pCairoContext, center.x, center.y); cairo_line_to (m_pCairoContext, secondHandle.x, secondHandle.y); cairo_stroke (m_pCairoContext); // draw the three handle-points */ draw_handle (&firstHandle); draw_handle (&secondHandle); draw_handle (¢er); return true; } bool CairoSamples::moving_arc_negative () const { if (!m_pCairoContext) return false; HandlePoint center = get_center (); double fRadius = get_radius (); double radiantAngle1 = get_angle_1 () * (M_PI / 180.0f); double radiantAngle2 = get_angle_2 () * (M_PI / 180.0f); HandlePoint firstHandle = { center.x + fRadius * cos (radiantAngle1), center.y + fRadius * sin (radiantAngle1) }; HandlePoint secondHandle = { center.x + fRadius * cos (radiantAngle2), center.y + fRadius * sin (radiantAngle2)}; draw_background (); // draw black arc cairo_set_line_width(m_pCairoContext, m_fLineWidth); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_arc_negative (m_pCairoContext, center.x, center.y, fRadius, radiantAngle1, radiantAngle2); cairo_stroke (m_pCairoContext); // draw the two "helper"-lines cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_set_line_width (m_pCairoContext, 0.005f); cairo_move_to (m_pCairoContext, center.x, center.y); cairo_line_to (m_pCairoContext, firstHandle.x, firstHandle.y); cairo_move_to (m_pCairoContext, center.x, center.y); cairo_line_to (m_pCairoContext, secondHandle.x, secondHandle.y); cairo_stroke (m_pCairoContext); // draw the three handle-points */ draw_handle (&firstHandle); draw_handle (&secondHandle); draw_handle (¢er); return true; } bool CairoSamples::moving_cairo_logo () const { if (!m_pCairoContext) return false; draw_background (); svg_cairo_t* pSVGContext; unsigned int uiWidth; unsigned int uiHeight; cairo_matrix_t matrix; HandlePoint offset = get_center (); svg_cairo_create (&pSVGContext); svg_cairo_parse (pSVGContext, "./cairo_logo.svg"); svg_cairo_get_size (pSVGContext, &uiWidth, &uiHeight); cairo_matrix_init_identity (&matrix); cairo_matrix_translate (&matrix, 5.5f, 6.5f); cairo_matrix_rotate (&matrix, get_angle_1 () * (M_PI/180.0)); cairo_matrix_scale (&matrix, 0.5f, 0.5f); cairo_set_matrix (m_pCairoContext, &matrix); svg_cairo_render (pSVGContext, m_pCairoContext); svg_cairo_destroy (pSVGContext); return true; } bool CairoSamples::moving_clip () const { if (!m_pCairoContext) return false; HandlePoint center = get_center (); double fRadius = get_radius () / 2.0f; HandlePoint handle = {center.x + fRadius * cos (0.0f), center.y + fRadius * sin (0.0f)}; draw_background (); // draw clipping arc/circle with black interior cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_arc (m_pCairoContext, center.x, center.y, fRadius, 0.0f, 2.0f * M_PI); cairo_clip (m_pCairoContext); // begin new path within clipping arc/circle // current path is not consumed by cairo_clip() cairo_new_path (m_pCairoContext); cairo_rectangle (m_pCairoContext, 0.0f, 0.0f, 1.0f, 1.0f); cairo_fill (m_pCairoContext); // draw two green diagonal lines cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_move_to (m_pCairoContext, 0.0f, 0.0f); cairo_line_to (m_pCairoContext, 1.0f, 1.0f); cairo_move_to (m_pCairoContext, 1.0f, 0.0f); cairo_line_to (m_pCairoContext, 0.0f, 1.0f); cairo_stroke (m_pCairoContext); // draw the two handle-points */ draw_handle (&handle); draw_handle (¢er); return true; } bool CairoSamples::moving_clip_image () const { if (!m_pCairoContext) return false; int iWidth; int iHeight; cairo_surface_t* pImage; HandlePoint center = get_center (); double fRadius = get_radius () / 2.0f; HandlePoint handle = {center.x + fRadius * cos (0.0f), center.y + fRadius * sin (0.0f)}; draw_background (); // draw clipping arc/circle cairo_arc (m_pCairoContext, center.x, center.y, fRadius, 0.0f, 2.0f * M_PI); cairo_clip (m_pCairoContext); // fill that clipping arc/circle with an image cairo_new_path (m_pCairoContext); pImage = cairo_image_surface_create_from_png (m_strImageFileName.c_str ()); iWidth = cairo_image_surface_get_width (pImage); iHeight = cairo_image_surface_get_height (pImage); //cairo_scale (m_pCairoContext, 1.0f / iWidth, 1.0f / iHeight); cairo_set_source_surface (m_pCairoContext, pImage, 0.0f, 0.0f); cairo_paint (m_pCairoContext); cairo_surface_destroy (pImage); // draw the two handle-points */ draw_handle (&handle); draw_handle (¢er); return true; } bool CairoSamples::moving_curve_to () const { if (!m_pCairoContext) return false; HandlePoint points[4]; points[0] = get_point1 (); points[1] = get_point2 (); points[2] = get_point3 (); points[3] = get_point4 (); draw_background (); // draw black bezier-curve cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_move_to (m_pCairoContext, points[0].x, points[0].y); cairo_curve_to (m_pCairoContext, points[1].x, points[1].y, points[2].x, points[2].y, points[3].x, points[3].y); cairo_stroke (m_pCairoContext); // draw red "helper" lines cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_set_line_width (m_pCairoContext, 0.005f); cairo_move_to (m_pCairoContext, points[0].x, points[0].y); cairo_line_to (m_pCairoContext, points[1].x, points[1].y); cairo_move_to (m_pCairoContext, points[2].x, points[2].y); cairo_line_to (m_pCairoContext, points[3].x, points[3].y); cairo_stroke (m_pCairoContext); // draw the three handle-points draw_handle (&points[0]); draw_handle (&points[1]); draw_handle (&points[2]); draw_handle (&points[3]); return true; } bool CairoSamples::moving_gradient () const { if (!m_pCairoContext) return false; HandlePoint center = get_center (); double fRadius = get_radius (); HandlePoint handle = {center.x + fRadius * cos (0.0f), center.y + fRadius * sin (0.0f)}; draw_background (); cairo_pattern_t* pPattern; pPattern = cairo_pattern_create_radial (center.x, center.y, fRadius, 0.5f, 0.5f, 0.5f); cairo_pattern_add_color_stop_rgba (pPattern, 0.0f, 1.0f, 1.0f, 0.1f, 0.85f); cairo_pattern_add_color_stop_rgba (pPattern, 1.0f, 0.7f, 0.1f, 0.1f, 1.0f); cairo_set_source (m_pCairoContext, pPattern); cairo_arc (m_pCairoContext, 0.5f, 0.5f, 0.3f, 0.0f, 2.0f * M_PI); cairo_fill (m_pCairoContext); cairo_pattern_destroy (pPattern); // draw the two handle-points */ draw_handle (¢er); draw_handle (&handle); return true; } bool CairoSamples::moving_gradient2 () const { if (!m_pCairoContext) return false; HandlePoint handle1 = get_point1 (); HandlePoint handle2 = get_point2 (); draw_background (); cairo_pattern_t* pPattern; pPattern = cairo_pattern_create_linear (handle1.x, handle1.y, handle2.x, handle2.y); cairo_pattern_set_filter (pPattern, m_cairoFilterMode); cairo_pattern_set_extend (pPattern, m_cairoExtendMode); cairo_pattern_add_color_stop_rgba (pPattern, 0.0f, 1.0f, 1.0f, 0.5f, 1.0f); cairo_pattern_add_color_stop_rgba (pPattern, 0.1f, 0.3f, 1.0f, 0.8f, 0.5f); cairo_pattern_add_color_stop_rgba (pPattern, 0.5f, 1.0f, 0.0f, 0.7f, 1.0f); cairo_pattern_add_color_stop_rgba (pPattern, 0.9f, 0.6f, 0.0f, 1.0f, 0.1f); cairo_pattern_add_color_stop_rgba (pPattern, 1.0f, 0.2f, 0.5f, 1.0f, 1.0f); cairo_set_source (m_pCairoContext, pPattern); cairo_rectangle (m_pCairoContext, 0.0f, 0.0f, 1.0f, 1.0f); cairo_fill (m_pCairoContext); cairo_pattern_destroy (pPattern); // draw the two handle-points */ draw_handle (&handle1); draw_handle (&handle2); return true; } bool CairoSamples::operator_add () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_ADD); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_atop () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_ATOP); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_atop_reverse () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_DEST_ATOP); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_in () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_IN); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_in_reverse () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_DEST_IN); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_out () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_OUT); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_out_reverse () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_DEST_OUT); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_over () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_over_reverse () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_DEST_OVER); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_saturate () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_SATURATE); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::operator_xor () const { if (!m_pCairoContext) return false; draw_background (); set_bg_svg ("freedesktop.svg"); cairo_set_operator (m_pCairoContext, CAIRO_OPERATOR_XOR); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.0f, 0.0f, 0.5f); cairo_rectangle (m_pCairoContext, 0.2f, 0.2f, 0.5f, 0.5f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_rectangle (m_pCairoContext, 0.4f, 0.4f, 0.4f, 0.4f); cairo_fill (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_rectangle (m_pCairoContext, 0.6f, 0.6f, 0.3f, 0.3f); cairo_fill (m_pCairoContext); return true; } bool CairoSamples::path () const { if (!m_pCairoContext) return false; draw_background (); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_move_to (m_pCairoContext, 0.5f, 0.1f); cairo_line_to (m_pCairoContext, 0.9f, 0.9f); cairo_rel_line_to (m_pCairoContext, -0.4f, 0.0f); cairo_curve_to (m_pCairoContext, 0.2f, 0.9f, 0.2f, 0.5f, 0.5f, 0.5f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::pattern_fill () const { if (!m_pCairoContext) return false; draw_background (); #define X_FUZZ 0.08 #define Y_FUZZ 0.08 #define X_INNER_RADIUS 0.3 #define Y_INNER_RADIUS 0.2 #define X_OUTER_RADIUS 0.45 #define Y_OUTER_RADIUS 0.35 #define SPIKES 10 int i; double x; double y; cairo_text_extents_t extents; srand (45); cairo_set_line_width (m_pCairoContext, m_fLineWidth); for (i = 0; i < SPIKES * 2; i++) { x = 0.5f + cos (M_PI * i / SPIKES) * X_INNER_RADIUS + (double) rand() * X_FUZZ / RAND_MAX; y = 0.5f + sin (M_PI * i / SPIKES) * Y_INNER_RADIUS + (double) rand() * Y_FUZZ / RAND_MAX; if (i == 0) cairo_move_to (m_pCairoContext, x, y); else cairo_line_to (m_pCairoContext, x, y); i++; x = 0.5f + cos (M_PI * i / SPIKES) * X_OUTER_RADIUS + (double) rand() * X_FUZZ / RAND_MAX; y = 0.5f + sin (M_PI * i / SPIKES) * Y_OUTER_RADIUS + (double) rand() * Y_FUZZ / RAND_MAX; cairo_line_to (m_pCairoContext, x, y); } cairo_close_path (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 1.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); cairo_select_font_face (m_pCairoContext, m_strFontFamily.c_str (), m_cairoFontSlant, m_cairoFontWeight); cairo_move_to (m_pCairoContext, x, y); cairo_text_path (m_pCairoContext, m_strSomeText.c_str ()); cairo_set_font_size (m_pCairoContext, 0.2f); cairo_text_extents (m_pCairoContext, m_strSomeText.c_str (), &extents); x = 0.5f - (extents.width / 2.0f + extents.x_bearing); y = 0.5f - (extents.height / 2.0f + extents.y_bearing); cairo_set_source_rgb (m_pCairoContext, 1.0f, 1.0f, 0.5f); cairo_fill (m_pCairoContext); cairo_move_to (m_pCairoContext, x, y); cairo_text_path (m_pCairoContext, m_strSomeText.c_str ()); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::set_line_cap () const { if (!m_pCairoContext) return false; draw_background (); // draw first (left-most) line, which the user can alter cairo_set_source_rgb (m_pCairoContext, 0.3f, 0.3f, 0.3f); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_line_cap (m_pCairoContext, m_cairoCapStyle); cairo_move_to (m_pCairoContext, 0.2f, 0.2); cairo_line_to (m_pCairoContext, 0.2f, 0.8); cairo_stroke (m_pCairoContext); // draw second line using a fixed line-cap style: round cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_set_line_width (m_pCairoContext, 0.12f); cairo_set_line_cap (m_pCairoContext, CAIRO_LINE_CAP_ROUND); cairo_move_to (m_pCairoContext, 0.4f, 0.2); cairo_line_to (m_pCairoContext, 0.4f, 0.8); cairo_stroke (m_pCairoContext); // draw third line using a fixed line-cap style: square cairo_set_line_cap (m_pCairoContext, CAIRO_LINE_CAP_SQUARE); cairo_move_to (m_pCairoContext, 0.6f, 0.2); cairo_line_to (m_pCairoContext, 0.6f, 0.8); cairo_stroke (m_pCairoContext); // draw fourth line using a fixed line-cap style: butt cairo_set_line_cap (m_pCairoContext, CAIRO_LINE_CAP_BUTT); cairo_move_to (m_pCairoContext, 0.8f, 0.2); cairo_line_to (m_pCairoContext, 0.8f, 0.8); cairo_stroke (m_pCairoContext); // draw helping lines cairo_set_line_width (m_pCairoContext, 0.005f); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_move_to (m_pCairoContext, 0.2f, 0.2f); cairo_line_to (m_pCairoContext, 0.2f, 0.8f); cairo_move_to (m_pCairoContext, 0.4f, 0.2f); cairo_line_to (m_pCairoContext, 0.4f, 0.8f); cairo_move_to (m_pCairoContext, 0.6f, 0.2f); cairo_line_to (m_pCairoContext, 0.6f, 0.8f); cairo_move_to (m_pCairoContext, 0.8f, 0.2f); cairo_line_to (m_pCairoContext, 0.8f, 0.8f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::set_line_join () const { if (!m_pCairoContext) return false; draw_background (); // draw first (top-left) joint cairo_set_source_rgb (m_pCairoContext, 0.3f, 0.3f, 0.3f); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.125f, 0.475f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); cairo_set_line_join (m_pCairoContext, m_cairoJoinStyle); cairo_stroke (m_pCairoContext); // draw second (top-right) joint using line-join style: miter cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_set_line_width (m_pCairoContext, 0.16f); cairo_move_to (m_pCairoContext, 0.625f, 0.475f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); cairo_set_line_join (m_pCairoContext, CAIRO_LINE_JOIN_MITER); cairo_stroke (m_pCairoContext); // draw third (bottom-left) joint using line-join style: bevel cairo_move_to (m_pCairoContext, 0.125f, 0.925f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); cairo_set_line_join (m_pCairoContext, CAIRO_LINE_JOIN_BEVEL); cairo_stroke (m_pCairoContext); // draw fourth (bottom-right) joint using line-join style: round cairo_move_to (m_pCairoContext, 0.625f, 0.925f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); cairo_set_line_join (m_pCairoContext, CAIRO_LINE_JOIN_ROUND); cairo_stroke (m_pCairoContext); // draw helping line (top-left) cairo_set_line_width (m_pCairoContext, 0.005f); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_move_to (m_pCairoContext, 0.125f, 0.475f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); // draw helping line (top-right) cairo_move_to (m_pCairoContext, 0.625f, 0.475f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); // draw helping line (bottom-left) cairo_move_to (m_pCairoContext, 0.125f, 0.925f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); // draw helping line (bottom-right) cairo_move_to (m_pCairoContext, 0.625f, 0.925f); cairo_rel_line_to (m_pCairoContext, 0.125f, -0.25f); cairo_rel_line_to (m_pCairoContext, 0.125f, 0.25f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::text_align_center () const { if (!m_pCairoContext) return false; draw_background (); // set font-attributes cairo_select_font_face (m_pCairoContext, m_strSomeText.c_str (), m_cairoFontSlant, m_cairoFontWeight); cairo_set_font_size (m_pCairoContext, m_fFontSize); // get texts extents cairo_text_extents_t extents; cairo_text_extents (m_pCairoContext, m_strSomeText.c_str (), &extents); // determine center point double fX; double fY; fX = 0.5f - (extents.width / 2.0f + extents.x_bearing); fY = 0.5f - (extents.height / 2.0f + extents.y_bearing); // draw the solid black text cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_move_to (m_pCairoContext, fX, fY); cairo_show_text (m_pCairoContext, m_strSomeText.c_str ()); // draw helping lines cairo_set_line_width (m_pCairoContext, 0.005f); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_move_to (m_pCairoContext, 0.5f, 0.0f); cairo_rel_line_to (m_pCairoContext, 0.0f, 1.0f); cairo_move_to (m_pCairoContext, 0.0f, 0.5f); cairo_rel_line_to (m_pCairoContext, 1.0f, 0.0f); cairo_stroke (m_pCairoContext); // draw handle draw_handle (fX, fY); return true; } bool CairoSamples::text () const { if (!m_pCairoContext) return false; draw_background (); // set font-attributes cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_select_font_face (m_pCairoContext, m_strFontFamily.c_str (), m_cairoFontSlant, m_cairoFontWeight); cairo_set_font_size (m_pCairoContext, m_fFontSize); // draw the solid black text cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_move_to (m_pCairoContext, 0.04f, 0.53f); cairo_show_text (m_pCairoContext, m_strSomeText.c_str ()); // draw the blue colored text with black outlines cairo_move_to (m_pCairoContext, 0.27f, 0.65f); cairo_text_path (m_pCairoContext, m_strSomeText.c_str ()); cairo_set_source_rgb (m_pCairoContext, 0.5f, 0.5f, 1.0f); cairo_fill_preserve (m_pCairoContext); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_stroke (m_pCairoContext); // draw the two handle-points draw_handle (0.04f, 0.53f); draw_handle (0.27f, 0.65f); return true; } bool CairoSamples::text_extents () const { if (!m_pCairoContext) return false; draw_background (); // set font-attributes cairo_select_font_face (m_pCairoContext, m_strFontFamily.c_str (), m_cairoFontSlant, m_cairoFontWeight); cairo_set_font_size (m_pCairoContext, m_fFontSize); // get texts extents cairo_text_extents_t extents; cairo_text_extents (m_pCairoContext, m_strSomeText.c_str (), &extents); double fX = 0.1f; double fY = 0.6f; // draw the solid black text cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_move_to (m_pCairoContext, fX, fY); cairo_show_text (m_pCairoContext, m_strSomeText.c_str ()); // draw helping lines cairo_set_line_width (m_pCairoContext, 0.005f); cairo_set_source_rgba (m_pCairoContext, 1.0f, 0.2f, 0.2f, 0.6f); cairo_move_to (m_pCairoContext, fX, fY); cairo_rel_line_to (m_pCairoContext, 0.0f, -extents.height); cairo_rel_line_to (m_pCairoContext, extents.width, 0.0f); cairo_rel_line_to (m_pCairoContext, extents.x_bearing, -extents.y_bearing); cairo_stroke (m_pCairoContext); // draw the handle-point draw_handle (fX, fY); return true; } bool CairoSamples::xxx_clip_rectangle () const { if (!m_pCairoContext) return false; draw_background (); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_new_path (m_pCairoContext); cairo_move_to (m_pCairoContext, .25f, .25f); cairo_line_to (m_pCairoContext, .25f, .75f); cairo_line_to (m_pCairoContext, .75f, .75f); cairo_line_to (m_pCairoContext, .75f, .25f); cairo_line_to (m_pCairoContext, .25f, .25f); cairo_close_path (m_pCairoContext); cairo_clip (m_pCairoContext); cairo_move_to (m_pCairoContext, 0.0f, 0.0f); cairo_line_to (m_pCairoContext, 1.0f, 1.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::xxx_dash () const { if (!m_pCairoContext) return false; draw_background (); double dashes[] = {0.20f, /* ink */ 0.05f, /* skip */ 0.05f, /* ink */ 0.05f /* skip*/}; int ndash = sizeof (dashes)/sizeof(dashes[0]); double offset = -0.2f; cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_line_cap (m_pCairoContext, m_cairoCapStyle); cairo_set_line_join (m_pCairoContext, m_cairoJoinStyle); cairo_set_dash (m_pCairoContext, dashes, ndash, offset); cairo_move_to (m_pCairoContext, 0.5f, 0.1f); cairo_line_to (m_pCairoContext, 0.9f, 0.9f); cairo_rel_line_to (m_pCairoContext, -0.4f, 0.0f); cairo_curve_to (m_pCairoContext, 0.2f, 0.9f, 0.2f, 0.5f, 0.5f, 0.5f); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::xxx_long_lines () const { if (!m_pCairoContext) return false; draw_background (); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.1f, -50.0f); cairo_line_to (m_pCairoContext, 0.1f, 50.0f); cairo_set_source_rgb (m_pCairoContext, 1.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.2f, -60.0f); cairo_line_to (m_pCairoContext, 0.2f, 60.0f); cairo_set_source_rgb (m_pCairoContext, 1.0f, 1.0f, 0.0f); cairo_stroke (m_pCairoContext); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.3f, -70.0f); cairo_line_to (m_pCairoContext, 0.3f, 70.0f); cairo_set_source_rgb (m_pCairoContext, 0.0f, 1.0f, 0.0f); cairo_stroke (m_pCairoContext); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_move_to (m_pCairoContext, 0.4f, -80.0f); cairo_line_to (m_pCairoContext, 0.4f, 80.0f); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 1.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::xxx_multi_segment_caps () const { if (!m_pCairoContext) return false; draw_background (); cairo_move_to (m_pCairoContext, 0.2f, 0.3f); cairo_line_to (m_pCairoContext, 0.8f, 0.3f); cairo_move_to (m_pCairoContext, 0.2f, 0.5f); cairo_line_to (m_pCairoContext, 0.8f, 0.5f); cairo_move_to (m_pCairoContext, 0.2f, 0.7f); cairo_line_to (m_pCairoContext, 0.8f, 0.7f); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_line_cap (m_pCairoContext, m_cairoCapStyle); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); return true; } bool CairoSamples::xxx_self_intersect () const { if (!m_pCairoContext) return false; draw_background (); cairo_move_to (m_pCairoContext, 0.3f, 0.3f); cairo_line_to (m_pCairoContext, 0.7f, 0.3f); cairo_line_to (m_pCairoContext, 0.5f, 0.3f); cairo_line_to (m_pCairoContext, 0.5f, 0.7f); cairo_set_line_width (m_pCairoContext, m_fLineWidth); cairo_set_line_cap (m_pCairoContext, m_cairoCapStyle); cairo_set_line_join (m_pCairoContext, m_cairoJoinStyle); cairo_set_source_rgb (m_pCairoContext, 0.0f, 0.0f, 0.0f); cairo_stroke (m_pCairoContext); return true; }