Index: skia/ext/vector_platform_device_cairo_linux.cc |
diff --git a/skia/ext/vector_platform_device_cairo_linux.cc b/skia/ext/vector_platform_device_cairo_linux.cc |
deleted file mode 100644 |
index 1d31cf666d170d322e19903ca70ebbc18df64c23..0000000000000000000000000000000000000000 |
--- a/skia/ext/vector_platform_device_cairo_linux.cc |
+++ /dev/null |
@@ -1,695 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "skia/ext/vector_platform_device_cairo_linux.h" |
- |
-#include <cairo.h> |
-#include <cairo-ft.h> |
- |
-#include <ft2build.h> |
-#include FT_FREETYPE_H |
- |
-#include <map> |
- |
-#include "base/lazy_instance.h" |
-#include "base/logging.h" |
-#include "skia/ext/bitmap_platform_device.h" |
-#include "third_party/skia/include/core/SkFontHost.h" |
-#include "third_party/skia/include/core/SkStream.h" |
-#include "third_party/skia/include/core/SkTypeface.h" |
- |
-namespace { |
- |
-struct FontInfo { |
- SkStream* font_stream; |
- FT_Face ft_face; |
- cairo_font_face_t* cairo_face; |
- cairo_user_data_key_t data_key; |
-}; |
- |
-typedef std::map<uint32_t, FontInfo> MapFontId2FontInfo; |
-static base::LazyInstance<MapFontId2FontInfo> g_map_font_id_to_font_info( |
- base::LINKER_INITIALIZED); |
- |
-// Wrapper for FT_Library that handles initialization and cleanup, and allows |
-// us to use a singleton. |
-class FtLibrary { |
- public: |
- FtLibrary() : library_(NULL) { |
- FT_Error ft_error = FT_Init_FreeType(&library_); |
- if (ft_error) { |
- DLOG(ERROR) << "Cannot initialize FreeType library for " \ |
- << "VectorPlatformDeviceCairo."; |
- } |
- } |
- |
- ~FtLibrary() { |
- if (library_) { |
- FT_Error ft_error = FT_Done_FreeType(library_); |
- library_ = NULL; |
- DCHECK_EQ(ft_error, 0); |
- } |
- } |
- |
- FT_Library library() { return library_; } |
- |
- private: |
- FT_Library library_; |
-}; |
-static base::LazyInstance<FtLibrary> g_ft_library(base::LINKER_INITIALIZED); |
- |
-// Verify cairo surface after creation/modification. |
-bool IsContextValid(cairo_t* context) { |
- return cairo_status(context) == CAIRO_STATUS_SUCCESS; |
-} |
- |
-} // namespace |
- |
-namespace skia { |
- |
-// static |
-SkDevice* VectorPlatformDeviceCairo::CreateDevice(cairo_t* context, int width, |
- int height, bool isOpaque) { |
- // TODO(myhuang): Here we might also have similar issues as those on Windows |
- // (vector_canvas_win.cc, http://crbug.com/18382 & http://crbug.com/18383). |
- // Please note that is_opaque is true when we use this class for printing. |
- // Fallback to bitmap when context is NULL. |
- if (!isOpaque || NULL == context) { |
- return BitmapPlatformDevice::Create(width, height, isOpaque); |
- } |
- |
- SkASSERT(cairo_status(context) == CAIRO_STATUS_SUCCESS); |
- SkASSERT(width > 0); |
- SkASSERT(height > 0); |
- |
- SkBitmap bitmap; |
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); |
- |
- return new VectorPlatformDeviceCairo(context, bitmap); |
-} |
- |
-VectorPlatformDeviceCairo::VectorPlatformDeviceCairo(PlatformSurface context, |
- const SkBitmap& bitmap) |
- : SkDevice(bitmap), |
- context_(context) { |
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); |
- |
- SetPlatformDevice(this, this); |
- |
- // Increase the reference count to keep the context alive. |
- cairo_reference(context_); |
- |
- transform_.reset(); |
-} |
- |
-VectorPlatformDeviceCairo::~VectorPlatformDeviceCairo() { |
- // Un-ref |context_| since we referenced it in the constructor. |
- cairo_destroy(context_); |
-} |
- |
-PlatformSurface VectorPlatformDeviceCairo::BeginPlatformPaint() { |
- return context_; |
-} |
- |
-void VectorPlatformDeviceCairo::DrawToNativeContext( |
- PlatformSurface surface, int x, int y, const PlatformRect* src_rect) { |
- // Should never be called on Linux. |
- SkASSERT(false); |
-} |
- |
-SkDevice* VectorPlatformDeviceCairo::onCreateCompatibleDevice( |
- SkBitmap::Config config, |
- int width, int height, |
- bool isOpaque, Usage) { |
- SkASSERT(config == SkBitmap::kARGB_8888_Config); |
- return CreateDevice(NULL, width, height, isOpaque); |
-} |
- |
-uint32_t VectorPlatformDeviceCairo::getDeviceCapabilities() { |
- return SkDevice::getDeviceCapabilities() | kVector_Capability; |
-} |
- |
-void VectorPlatformDeviceCairo::drawBitmap(const SkDraw& draw, |
- const SkBitmap& bitmap, |
- const SkIRect* srcRectOrNull, |
- const SkMatrix& matrix, |
- const SkPaint& paint) { |
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); |
- |
- // Load the temporary matrix. This is what will translate, rotate and resize |
- // the bitmap. |
- SkMatrix actual_transform(transform_); |
- actual_transform.preConcat(matrix); |
- LoadTransformToContext(actual_transform); |
- |
- InternalDrawBitmap(bitmap, 0, 0, paint); |
- |
- // Restore the original matrix. |
- LoadTransformToContext(transform_); |
-} |
- |
-void VectorPlatformDeviceCairo::drawDevice(const SkDraw& draw, |
- SkDevice* device, |
- int x, |
- int y, |
- const SkPaint& paint) { |
- SkASSERT(device); |
- |
- // TODO(myhuang): We may also have to consider http://b/1183870 . |
- drawSprite(draw, device->accessBitmap(false), x, y, paint); |
-} |
- |
-void VectorPlatformDeviceCairo::drawPaint(const SkDraw& draw, |
- const SkPaint& paint) { |
- // Bypass the current transformation matrix. |
- LoadIdentityTransformToContext(); |
- |
- // TODO(myhuang): Is there a better way to do this? |
- SkRect rect; |
- rect.fLeft = 0; |
- rect.fTop = 0; |
- rect.fRight = SkIntToScalar(width() + 1); |
- rect.fBottom = SkIntToScalar(height() + 1); |
- drawRect(draw, rect, paint); |
- |
- // Restore the original matrix. |
- LoadTransformToContext(transform_); |
-} |
- |
-void VectorPlatformDeviceCairo::drawPath(const SkDraw& draw, |
- const SkPath& path, |
- const SkPaint& paint, |
- const SkMatrix* prePathMatrix, |
- bool pathIsMutable) { |
- if (paint.getPathEffect()) { |
- // Apply the path effect forehand. |
- SkPath path_modified; |
- paint.getFillPath(path, &path_modified); |
- |
- // Removes the path effect from the temporary SkPaint object. |
- SkPaint paint_no_effet(paint); |
- SkSafeUnref(paint_no_effet.setPathEffect(NULL)); |
- |
- // Draw the calculated path. |
- drawPath(draw, path_modified, paint_no_effet); |
- return; |
- } |
- |
- // Setup paint color. |
- ApplyPaintColor(paint); |
- |
- SkPaint::Style style = paint.getStyle(); |
- // Setup fill style. |
- if (style & SkPaint::kFill_Style) { |
- ApplyFillStyle(path); |
- } |
- |
- // Setup stroke style. |
- if (style & SkPaint::kStroke_Style) { |
- ApplyStrokeStyle(paint); |
- } |
- |
- // Iterate path verbs. |
- // TODO(myhuang): Is there a better way to do this? |
- SkPoint current_points[4]; |
- SkPath::Iter iter(path, false); |
- for (SkPath::Verb verb = iter.next(current_points); |
- verb != SkPath::kDone_Verb; |
- verb = iter.next(current_points)) { |
- switch (verb) { |
- case SkPath::kMove_Verb: { // iter.next returns 1 point |
- cairo_move_to(context_, current_points[0].fX, current_points[0].fY); |
- } break; |
- |
- case SkPath::kLine_Verb: { // iter.next returns 2 points |
- cairo_line_to(context_, current_points[1].fX, current_points[1].fY); |
- } break; |
- |
- case SkPath::kQuad_Verb: { // iter.next returns 3 points |
- // Degree elevation (quadratic to cubic). |
- // c1 = (2 * p1 + p0) / 3 |
- // c2 = (2 * p1 + p2) / 3 |
- current_points[1].scale(2.); // p1 *= 2.0; |
- SkScalar c1_X = (current_points[1].fX + current_points[0].fX) / 3.; |
- SkScalar c1_Y = (current_points[1].fY + current_points[0].fY) / 3.; |
- SkScalar c2_X = (current_points[1].fX + current_points[2].fX) / 3.; |
- SkScalar c2_Y = (current_points[1].fY + current_points[2].fY) / 3.; |
- cairo_curve_to(context_, |
- c1_X, c1_Y, |
- c2_X, c2_Y, |
- current_points[2].fX, current_points[2].fY); |
- } break; |
- |
- case SkPath::kCubic_Verb: { // iter.next returns 4 points |
- cairo_curve_to(context_, |
- current_points[1].fX, current_points[1].fY, |
- current_points[2].fX, current_points[2].fY, |
- current_points[3].fX, current_points[3].fY); |
- } break; |
- |
- case SkPath::kClose_Verb: { // iter.next returns 1 point (the last pt). |
- cairo_close_path(context_); |
- } break; |
- |
- default: { |
- // Should not reach here! |
- SkASSERT(false); |
- } break; |
- } |
- } |
- |
- DoPaintStyle(paint); |
-} |
- |
-void VectorPlatformDeviceCairo::drawPoints(const SkDraw& draw, |
- SkCanvas::PointMode mode, |
- size_t count, |
- const SkPoint pts[], |
- const SkPaint& paint) { |
- SkASSERT(pts); |
- |
- if (!count) |
- return; |
- |
- // Setup paint color. |
- ApplyPaintColor(paint); |
- |
- // Setup stroke style. |
- ApplyStrokeStyle(paint); |
- |
- switch (mode) { |
- case SkCanvas::kPoints_PointMode: { |
- // There is a bug in Cairo that it won't draw anything when using some |
- // specific caps, e.g. SkPaint::kSquare_Cap. This is because Cairo does |
- // not have enough/ambiguous direction information. One possible work- |
- // around is to draw a really short line. |
- for (size_t i = 0; i < count; ++i) { |
- double x = pts[i].fX; |
- double y = pts[i].fY; |
- cairo_move_to(context_, x, y); |
- cairo_line_to(context_, x+.01, y); |
- } |
- } break; |
- |
- case SkCanvas::kLines_PointMode: { |
- if (count % 2) { |
- SkASSERT(false); |
- return; |
- } |
- |
- for (size_t i = 0; i < count >> 1; ++i) { |
- double x1 = pts[i << 1].fX; |
- double y1 = pts[i << 1].fY; |
- double x2 = pts[(i << 1) + 1].fX; |
- double y2 = pts[(i << 1) + 1].fY; |
- cairo_move_to(context_, x1, y1); |
- cairo_line_to(context_, x2, y2); |
- } |
- } break; |
- |
- case SkCanvas::kPolygon_PointMode: { |
- double x = pts[0].fX; |
- double y = pts[0].fY; |
- cairo_move_to(context_, x, y); |
- for (size_t i = 1; i < count; ++i) { |
- x = pts[i].fX; |
- y = pts[i].fY; |
- cairo_line_to(context_, x, y); |
- } |
- } break; |
- |
- default: |
- SkASSERT(false); |
- return; |
- } |
- cairo_stroke(context_); |
-} |
- |
-// TODO(myhuang): Embed fonts/texts into PDF surface. |
-// Please NOTE that len records text's length in byte, not uint16_t. |
-void VectorPlatformDeviceCairo::drawPosText(const SkDraw& draw, |
- const void* text, |
- size_t len, |
- const SkScalar pos[], |
- SkScalar constY, |
- int scalarsPerPos, |
- const SkPaint& paint) { |
- SkASSERT(text); |
- SkASSERT(pos); |
- SkASSERT(paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding); |
- // Each pos should contain either only x, or (x, y). |
- SkASSERT((scalarsPerPos == 1) || (scalarsPerPos == 2)); |
- |
- if (!len) |
- return; |
- |
- // Text color. |
- ApplyPaintColor(paint); |
- |
- const uint16_t* glyph_ids = static_cast<const uint16_t*>(text); |
- |
- // The style is either kFill_Style or kStroke_Style. |
- if (paint.getStyle() & SkPaint::kStroke_Style) { |
- ApplyStrokeStyle(paint); |
- |
- // Draw each glyph by its path. |
- for (size_t i = 0; i < len / sizeof(uint16_t); ++i) { |
- uint16_t glyph_id = glyph_ids[i]; |
- SkPath textPath; |
- paint.getTextPath(&glyph_id, |
- sizeof(uint16_t), |
- pos[i * scalarsPerPos], |
- (scalarsPerPos == 1) ? |
- constY : |
- pos[i * scalarsPerPos + 1], |
- &textPath); |
- drawPath(draw, textPath, paint); |
- } |
- } else { // kFill_Style. |
- // Selects correct font. |
- if (!SelectFontById(paint.getTypeface()->uniqueID())) { |
- SkASSERT(false); |
- return; |
- } |
- cairo_set_font_size(context_, paint.getTextSize()); |
- |
- // Draw glyphs. |
- for (size_t i = 0; i < len / sizeof(uint16_t); ++i) { |
- uint16_t glyph_id = glyph_ids[i]; |
- |
- cairo_glyph_t glyph; |
- glyph.index = glyph_id; |
- glyph.x = pos[i * scalarsPerPos]; |
- glyph.y = (scalarsPerPos == 1) ? constY : pos[i * scalarsPerPos + 1]; |
- |
- cairo_show_glyphs(context_, &glyph, 1); |
- } |
- } |
-} |
- |
-void VectorPlatformDeviceCairo::drawRect(const SkDraw& draw, |
- const SkRect& rect, |
- const SkPaint& paint) { |
- if (paint.getPathEffect()) { |
- // Draw a path instead. |
- SkPath path_orginal; |
- path_orginal.addRect(rect); |
- |
- // Apply the path effect to the rect. |
- SkPath path_modified; |
- paint.getFillPath(path_orginal, &path_modified); |
- |
- // Removes the path effect from the temporary SkPaint object. |
- SkPaint paint_no_effet(paint); |
- SkSafeUnref(paint_no_effet.setPathEffect(NULL)); |
- |
- // Draw the calculated path. |
- drawPath(draw, path_modified, paint_no_effet); |
- return; |
- } |
- |
- // Setup color. |
- ApplyPaintColor(paint); |
- |
- // Setup stroke style. |
- ApplyStrokeStyle(paint); |
- |
- // Draw rectangle. |
- cairo_rectangle(context_, |
- rect.fLeft, rect.fTop, |
- rect.fRight - rect.fLeft, rect.fBottom - rect.fTop); |
- |
- DoPaintStyle(paint); |
-} |
- |
-void VectorPlatformDeviceCairo::drawSprite(const SkDraw& draw, |
- const SkBitmap& bitmap, |
- int x, int y, |
- const SkPaint& paint) { |
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); |
- |
- LoadIdentityTransformToContext(); |
- |
- InternalDrawBitmap(bitmap, x, y, paint); |
- |
- // Restore the original matrix. |
- LoadTransformToContext(transform_); |
-} |
- |
-void VectorPlatformDeviceCairo::drawText(const SkDraw& draw, |
- const void* text, |
- size_t byteLength, |
- SkScalar x, |
- SkScalar y, |
- const SkPaint& paint) { |
- // This function isn't used in the code. Verify this assumption. |
- SkASSERT(false); |
-} |
- |
- |
-void VectorPlatformDeviceCairo::drawTextOnPath(const SkDraw& draw, |
- const void* text, |
- size_t len, |
- const SkPath& path, |
- const SkMatrix* matrix, |
- const SkPaint& paint) { |
- // This function isn't used in the code. Verify this assumption. |
- SkASSERT(false); |
-} |
- |
-void VectorPlatformDeviceCairo::drawVertices(const SkDraw& draw, |
- SkCanvas::VertexMode vmode, |
- int vertexCount, |
- const SkPoint vertices[], |
- const SkPoint texs[], |
- const SkColor colors[], |
- SkXfermode* xmode, |
- const uint16_t indices[], |
- int indexCount, |
- const SkPaint& paint) { |
- // This function isn't used in the code. Verify this assumption. |
- SkASSERT(false); |
-} |
- |
-void VectorPlatformDeviceCairo::setMatrixClip(const SkMatrix& transform, |
- const SkRegion& region, |
- const SkClipStack&) { |
- clip_region_ = region; |
- if (!clip_region_.isEmpty()) |
- LoadClipRegion(clip_region_); |
- |
- transform_ = transform; |
- LoadTransformToContext(transform_); |
-} |
- |
-void VectorPlatformDeviceCairo::ApplyPaintColor(const SkPaint& paint) { |
- SkColor color = paint.getColor(); |
- double a = static_cast<double>(SkColorGetA(color)) / 255.; |
- double r = static_cast<double>(SkColorGetR(color)) / 255.; |
- double g = static_cast<double>(SkColorGetG(color)) / 255.; |
- double b = static_cast<double>(SkColorGetB(color)) / 255.; |
- |
- cairo_set_source_rgba(context_, r, g, b, a); |
-} |
- |
-void VectorPlatformDeviceCairo::ApplyFillStyle(const SkPath& path) { |
- // Setup fill style. |
- // TODO(myhuang): Cairo does NOT support all skia fill rules!! |
- cairo_set_fill_rule(context_, |
- static_cast<cairo_fill_rule_t>(path.getFillType())); |
-} |
- |
-void VectorPlatformDeviceCairo::ApplyStrokeStyle(const SkPaint& paint) { |
- // Line width. |
- cairo_set_line_width(context_, paint.getStrokeWidth()); |
- |
- // Line join. |
- cairo_set_line_join(context_, |
- static_cast<cairo_line_join_t>(paint.getStrokeJoin())); |
- |
- // Line cap. |
- cairo_set_line_cap(context_, |
- static_cast<cairo_line_cap_t>(paint.getStrokeCap())); |
-} |
- |
-void VectorPlatformDeviceCairo::DoPaintStyle(const SkPaint& paint) { |
- SkPaint::Style style = paint.getStyle(); |
- |
- switch (style) { |
- case SkPaint::kFill_Style: { |
- cairo_fill(context_); |
- } break; |
- |
- case SkPaint::kStroke_Style: { |
- cairo_stroke(context_); |
- } break; |
- |
- case SkPaint::kStrokeAndFill_Style: { |
- cairo_fill_preserve(context_); |
- cairo_stroke(context_); |
- } break; |
- |
- default: |
- SkASSERT(false); |
- } |
-} |
- |
-void VectorPlatformDeviceCairo::InternalDrawBitmap(const SkBitmap& bitmap, |
- int x, int y, |
- const SkPaint& paint) { |
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); |
- |
- unsigned char alpha = paint.getAlpha(); |
- |
- if (alpha == 0) |
- return; |
- |
- int src_size_x = bitmap.width(); |
- int src_size_y = bitmap.height(); |
- |
- if (!src_size_x || !src_size_y) |
- return; |
- |
- SkAutoLockPixels image_lock(bitmap); |
- |
- cairo_surface_t* bitmap_surface = |
- cairo_image_surface_create_for_data( |
- reinterpret_cast<unsigned char*>(bitmap.getPixels()), |
- CAIRO_FORMAT_ARGB32, src_size_x, src_size_y, bitmap.rowBytes()); |
- |
- cairo_set_source_surface(context_, bitmap_surface, x, y); |
- cairo_paint_with_alpha(context_, static_cast<double>(alpha) / 255.); |
- |
- cairo_surface_destroy(bitmap_surface); |
-} |
- |
-void VectorPlatformDeviceCairo::LoadClipRegion(const SkRegion& clip) { |
- cairo_reset_clip(context_); |
- |
- LoadIdentityTransformToContext(); |
- |
- // TODO(myhuang): Support non-rect clips. |
- SkIRect bounding = clip.getBounds(); |
- cairo_rectangle(context_, bounding.fLeft, bounding.fTop, |
- bounding.fRight - bounding.fLeft, |
- bounding.fBottom - bounding.fTop); |
- cairo_clip(context_); |
- |
- // Restore the original matrix. |
- LoadTransformToContext(transform_); |
-} |
- |
-void VectorPlatformDeviceCairo::LoadIdentityTransformToContext() { |
- SkMatrix identity; |
- identity.reset(); |
- LoadTransformToContext(identity); |
-} |
- |
-void VectorPlatformDeviceCairo::LoadTransformToContext(const SkMatrix& matrix) { |
- cairo_matrix_t m; |
- m.xx = matrix[SkMatrix::kMScaleX]; |
- m.xy = matrix[SkMatrix::kMSkewX]; |
- m.x0 = matrix[SkMatrix::kMTransX]; |
- m.yx = matrix[SkMatrix::kMSkewY]; |
- m.yy = matrix[SkMatrix::kMScaleY]; |
- m.y0 = matrix[SkMatrix::kMTransY]; |
- cairo_set_matrix(context_, &m); |
-} |
- |
-bool VectorPlatformDeviceCairo::SelectFontById(uint32_t font_id) { |
- DCHECK(IsContextValid(context_)); |
- DCHECK(SkFontHost::ValidFontID(font_id)); |
- |
- FtLibrary* ft_library = g_ft_library.Pointer(); |
- if (!ft_library->library()) |
- return false; |
- |
- // Checks if we have a cache hit. |
- MapFontId2FontInfo* g_font_cache = g_map_font_id_to_font_info.Pointer(); |
- DCHECK(g_font_cache); |
- |
- MapFontId2FontInfo::iterator it = g_font_cache->find(font_id); |
- if (it != g_font_cache->end()) { |
- cairo_set_font_face(context_, it->second.cairo_face); |
- if (IsContextValid(context_)) { |
- return true; |
- } else { |
- NOTREACHED() << "Cannot set font face in Cairo!"; |
- return false; |
- } |
- } |
- |
- // Cache missed. We need to load and create the font. |
- FontInfo new_font_info = {0}; |
- new_font_info.font_stream = SkFontHost::OpenStream(font_id); |
- DCHECK(new_font_info.font_stream); |
- size_t stream_size = new_font_info.font_stream->getLength(); |
- DCHECK(stream_size) << "The Font stream has nothing!"; |
- |
- FT_Error ft_error = FT_New_Memory_Face( |
- ft_library->library(), |
- static_cast<FT_Byte*>( |
- const_cast<void*>(new_font_info.font_stream->getMemoryBase())), |
- stream_size, |
- 0, |
- &new_font_info.ft_face); |
- |
- if (ft_error) { |
- new_font_info.font_stream->unref(); |
- DLOG(ERROR) << "Cannot create FT_Face!"; |
- SkASSERT(false); |
- return false; |
- } |
- |
- new_font_info.cairo_face = cairo_ft_font_face_create_for_ft_face( |
- new_font_info.ft_face, 0); |
- DCHECK(new_font_info.cairo_face) << "Cannot create font in Cairo!"; |
- |
- // Manage |new_font_info.ft_face|'s life by Cairo. |
- cairo_status_t status = cairo_font_face_set_user_data( |
- new_font_info.cairo_face, |
- &new_font_info.data_key, |
- new_font_info.ft_face, |
- reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face)); |
- |
- if (status != CAIRO_STATUS_SUCCESS) { |
- DLOG(ERROR) << "Cannot set font's user data in Cairo!"; |
- cairo_font_face_destroy(new_font_info.cairo_face); |
- FT_Done_Face(new_font_info.ft_face); |
- new_font_info.font_stream->unref(); |
- SkASSERT(false); |
- return false; |
- } |
- |
- // Inserts |new_font_info| info |g_font_cache|. |
- (*g_font_cache)[font_id] = new_font_info; |
- |
- cairo_set_font_face(context_, new_font_info.cairo_face); |
- if (IsContextValid(context_)) { |
- return true; |
- } |
- |
- DLOG(ERROR) << "Connot set font face in Cairo!"; |
- return false; |
-} |
- |
-// static |
-void VectorPlatformDeviceCairo::ClearFontCache() { |
- MapFontId2FontInfo* g_font_cache = g_map_font_id_to_font_info.Pointer(); |
- DCHECK(g_font_cache); |
- |
- for (MapFontId2FontInfo::iterator it = g_font_cache->begin(); |
- it !=g_font_cache->end(); |
- ++it) { |
- DCHECK(it->second.cairo_face); |
- DCHECK(it->second.font_stream); |
- |
- cairo_font_face_destroy(it->second.cairo_face); |
- // |it->second.ft_face| is handled by Cairo. |
- it->second.font_stream->unref(); |
- } |
- g_font_cache->clear(); |
-} |
- |
-} // namespace skia |