mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-10-06 00:30:10 -06:00
Sdraw...
git-svn-id: svn://ultimatepp.org/upp/trunk@733 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
bac1832c94
commit
b5691c2c44
227 changed files with 128457 additions and 16 deletions
223
uppdev/plugin/cairo/Cairo.h
Normal file
223
uppdev/plugin/cairo/Cairo.h
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
#ifndef _plugin_cairo_Cairo_h_
|
||||
#define _plugin_cairo_Cairo_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
#include <Draw/Draw.h>
|
||||
|
||||
#include "lib/cairo.h"
|
||||
#include "lib/cairo-svg.h"
|
||||
#include "lib/cairo-pdf.h"
|
||||
#include "CairoPattern.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class Cairo : public NoCopy
|
||||
{
|
||||
private:
|
||||
cairo_surface_t *_surface;
|
||||
cairo_t *_context;
|
||||
int _width, _height;
|
||||
|
||||
void DestroySurface()
|
||||
{
|
||||
if (_context != NULL)
|
||||
{
|
||||
cairo_status_t status = cairo_status(_context);
|
||||
ASSERT_(status == CAIRO_STATUS_SUCCESS, cairo_status_to_string(status));
|
||||
cairo_destroy(_context);
|
||||
}
|
||||
|
||||
if (_surface != NULL)
|
||||
cairo_surface_destroy(_surface);
|
||||
}
|
||||
|
||||
public:
|
||||
Cairo()
|
||||
: _surface(NULL),
|
||||
_context(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~Cairo()
|
||||
{
|
||||
DestroySurface();
|
||||
}
|
||||
|
||||
int GetWidth() { return _width; }
|
||||
int GetHeight() { return _height; }
|
||||
|
||||
void SetSurface(cairo_surface_t *surface, int width, int height);
|
||||
void SetSurface(ImageBuffer &img);
|
||||
void CreateSvgSurface(String const &filename, double widthInPoints = 595, double heightInPoints = 841); // DIN-A4 default size
|
||||
void CreatePdfSurface(String const &filename, double widthInPoints = 595, double heightInPoints = 841); // DIN-A4 default size
|
||||
|
||||
cairo_t *GetContext()
|
||||
{
|
||||
return _context;
|
||||
}
|
||||
|
||||
cairo_surface_t *GetSurface()
|
||||
{
|
||||
return _surface;
|
||||
}
|
||||
|
||||
bool HasContext()
|
||||
{
|
||||
return _context != NULL;
|
||||
}
|
||||
|
||||
void Clear(Color const &color)
|
||||
{
|
||||
SetSourceRGB(color);
|
||||
Paint();
|
||||
}
|
||||
|
||||
/*******************************************************************************************************/
|
||||
/************** TODO: remove the following 2 methods!!! Replace them with a dedicated font system ******/
|
||||
/*******************************************************************************************************/
|
||||
void DrawText(double x, double y, char const * const text, double size, Color ink)
|
||||
{
|
||||
cairo_t *context = GetContext();
|
||||
ASSERT(context != NULL);
|
||||
|
||||
cairo_set_font_size(context, size);
|
||||
|
||||
Save();
|
||||
|
||||
Translate(x, y + size);
|
||||
|
||||
SetSourceRGB(ink);
|
||||
cairo_show_text(context, text);
|
||||
|
||||
NewPath();
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
void DrawTextCenter(double x, double y, double width, char const * const text, double size, Color ink)
|
||||
{
|
||||
cairo_t *context = GetContext();
|
||||
ASSERT(context != NULL);
|
||||
|
||||
cairo_set_font_size(context, size);
|
||||
|
||||
// measure string
|
||||
cairo_text_extents_t extents;
|
||||
cairo_text_extents(context, text, &extents);
|
||||
|
||||
double startX = x + (width / 2.0) - (extents.width / 2.0);
|
||||
|
||||
Save();
|
||||
|
||||
Translate(startX, y + size);
|
||||
|
||||
SetSourceRGB(ink);
|
||||
cairo_show_text(context, text);
|
||||
|
||||
NewPath();
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
/*
|
||||
* Cairo cairo_t methods
|
||||
* http://cairographics.org/manual/cairo-cairo-t.html
|
||||
*/
|
||||
void Save();
|
||||
void Restore();
|
||||
void PushGroup();
|
||||
//cairo_push_group_with_content
|
||||
void PopGroup();
|
||||
void PopGroupToSource();
|
||||
//cairo_get_group_target
|
||||
void SetSourceRGB(double r, double g, double b);
|
||||
void SetSourceRGB(Color const &color);
|
||||
void SetSourceRGBA(double r, double g, double b, double a);
|
||||
void SetSource(CairoPattern &pattern);
|
||||
//cairo_set_source_surface
|
||||
//cairo_get_source
|
||||
void SetAntialias(cairo_antialias_t antialias);
|
||||
cairo_antialias_t GetAntialias();
|
||||
void SetDash(double const * dashes, int numDashes, double offset);
|
||||
//cairo_get_dash_count
|
||||
//cairo_get_dash
|
||||
void SetFillRule(cairo_fill_rule_t fillRule);
|
||||
cairo_fill_rule_t GetFillRule();
|
||||
void SetLineCap(cairo_line_cap_t lineCap);
|
||||
cairo_line_cap_t GetLineCap();
|
||||
void SetLineJoin(cairo_line_join_t lineJoin);
|
||||
cairo_line_join_t GetLineJoin();
|
||||
void SetLineWidth(double width);
|
||||
double GetLineWidth();
|
||||
void SetMiterLimit(double limit);
|
||||
double GetMiterLimit();
|
||||
void SetOperator(cairo_operator_t op);
|
||||
cairo_operator_t GetOperator();
|
||||
void SetTolerance(double tolerance);
|
||||
double GetTolerance();
|
||||
void Clip(bool preserve = false);
|
||||
//cairo_clip_extents
|
||||
//cairo_reset_clip
|
||||
//cairo_rectangle_list_destroy
|
||||
//cairo_copy_clip_rectangle_list
|
||||
void Fill(bool preserve = false);
|
||||
//cairo_fill_extents
|
||||
//cairo_in_fill
|
||||
//cairo_mask
|
||||
//cairo_mask_surface
|
||||
void Paint(double alpha = 1.0);
|
||||
void Stroke(bool preserve = false);
|
||||
//cairo_stroke_extents
|
||||
//cairo_in_stroke
|
||||
//cairo_copy_page
|
||||
//cairo_show_page
|
||||
//cairo_get_reference_count probably not needed
|
||||
//cairo_set_user_data probably not needed
|
||||
//cairo_get_user_data probably not needed
|
||||
|
||||
/*
|
||||
* Cairo transformation methods
|
||||
* http://cairographics.org/manual/cairo-Transformations.html
|
||||
*/
|
||||
void Translate(double tx, double ty);
|
||||
void Scale(double sx, double sy);
|
||||
void Rotate(double angle);
|
||||
//cairo_transform
|
||||
//cairo_set_matrix
|
||||
//cairo_get_matrix
|
||||
void IdentityMatrix();
|
||||
//cairo_user_to_device
|
||||
//cairo_user_to_device_distance
|
||||
//cairo_device_to_user
|
||||
//cairo_device_to_user_distance
|
||||
|
||||
/*
|
||||
* Cairo path methods
|
||||
* http://cairographics.org/manual/cairo-Paths.html
|
||||
*/
|
||||
//cairo_copy_path
|
||||
//cairo_copy_path_flat
|
||||
//cairo_path_destroy
|
||||
//cairo_append_path
|
||||
//cairo_has_current_point
|
||||
Pointf GetCurrentPoint();
|
||||
void NewPath();
|
||||
//cairo_new_sub_path
|
||||
void ClosePath();
|
||||
void Arc(double xc, double yc, double radius, double angle1, double angle2);
|
||||
//cairo_arc_negative
|
||||
void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
void LineTo(double x, double y);
|
||||
void MoveTo(double x, double y);
|
||||
void Rectangle(double x, double y, double width, double height);
|
||||
//cairo_glyph_path
|
||||
//cairo_text_path
|
||||
void RelCurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
void RelLineTo(double x, double y);
|
||||
void RelMoveTo(double x, double y);
|
||||
//cairo_path_extents
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
264
uppdev/plugin/cairo/CairoCtrl.h
Normal file
264
uppdev/plugin/cairo/CairoCtrl.h
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
#ifndef _plugin_cairo_CairoCtrl_h_
|
||||
#define _plugin_cairo_CairoCtrl_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
#include "Cairo.h"
|
||||
#include "CairoDraw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
#include "lib/cairo-win32.h"
|
||||
|
||||
class CairoCtrl : public DHCtrl
|
||||
{
|
||||
private:
|
||||
Drawing const *_drawing;
|
||||
Color const *_backgroundColor;
|
||||
HDC _hDC;
|
||||
Cairo _cairo;
|
||||
bool _doubleBuffering;
|
||||
|
||||
void DoPaint()
|
||||
{
|
||||
if (!_cairo.HasContext())
|
||||
return;
|
||||
|
||||
CairoDraw draw(_cairo);
|
||||
|
||||
if (_drawing == NULL)
|
||||
{
|
||||
if (_backgroundColor != NULL)
|
||||
_cairo.Clear(*_backgroundColor);
|
||||
|
||||
CairoPaint(_cairo);
|
||||
UppPaint(draw);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cairo.Clear(_backgroundColor == NULL ? White() : *_backgroundColor);
|
||||
|
||||
Size drawingSize = _drawing->GetSize();
|
||||
Size size = GetSize();
|
||||
Size drawSize = size;
|
||||
int dx = 0, dy = 0;
|
||||
|
||||
if(drawingSize.cy * size.cx < size.cy * drawingSize.cx)
|
||||
{
|
||||
drawSize.cy = drawingSize.cy * size.cx / drawingSize.cx;
|
||||
dy = (size.cy - drawSize.cy) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawSize.cx = drawingSize.cx * size.cy / drawingSize.cy;
|
||||
dx = (size.cx - drawSize.cx) / 2;
|
||||
}
|
||||
|
||||
draw.Clipoff(dx, dy, drawSize.cx, drawSize.cy);
|
||||
draw.DrawDrawing(drawSize, *_drawing);
|
||||
draw.End();
|
||||
}
|
||||
|
||||
if (_doubleBuffering)
|
||||
BitBlt(_hDC, Point(0, 0), cairo_win32_surface_get_dc(_cairo.GetSurface()), GetSize());
|
||||
}
|
||||
|
||||
protected:
|
||||
// Called on paint events
|
||||
virtual void CairoPaint(Cairo &cairo) { WhenCairoPaint(cairo); }
|
||||
virtual void UppPaint(Draw &draw) { WhenPaint(draw); }
|
||||
|
||||
public:
|
||||
Callback1<Cairo &> WhenCairoPaint;
|
||||
Callback1<Draw &> WhenPaint;
|
||||
|
||||
CairoCtrl()
|
||||
: _drawing(NULL),
|
||||
_hDC(NULL),
|
||||
_doubleBuffering(true),
|
||||
_backgroundColor(NULL)
|
||||
{}
|
||||
|
||||
~CairoCtrl()
|
||||
{
|
||||
if (_hDC != NULL)
|
||||
ReleaseDC(GetHWND(), _hDC);
|
||||
|
||||
if (_backgroundColor != NULL)
|
||||
delete _backgroundColor;
|
||||
}
|
||||
|
||||
void Set(Drawing const * const drawing)
|
||||
{
|
||||
_drawing = drawing;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void Background(Color const &color)
|
||||
{
|
||||
if (_backgroundColor != NULL)
|
||||
delete _backgroundColor;
|
||||
|
||||
_backgroundColor = new Color(color);
|
||||
}
|
||||
|
||||
void SetDoubleBuffering(bool buffer = true)
|
||||
{
|
||||
_doubleBuffering = buffer;
|
||||
State(LAYOUTPOS);
|
||||
}
|
||||
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if(message == WM_PAINT)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(GetHWND(), &ps);
|
||||
DoPaint();
|
||||
EndPaint(GetHWND(), &ps);
|
||||
return 0;
|
||||
}
|
||||
else if(message == WM_ERASEBKGND)
|
||||
return 1;
|
||||
|
||||
return DHCtrl::WindowProc(message, wParam, lParam);
|
||||
}
|
||||
|
||||
virtual void State(int reason)
|
||||
{
|
||||
DHCtrl::State(reason);
|
||||
|
||||
if (reason == OPEN || reason == LAYOUTPOS)
|
||||
{
|
||||
HWND hwnd = GetHWND();
|
||||
if (hwnd != NULL)
|
||||
_hDC = ::GetDC(hwnd);
|
||||
|
||||
if (_hDC != NULL)
|
||||
{
|
||||
if (_doubleBuffering)
|
||||
_cairo.SetSurface(cairo_win32_surface_create_with_ddb(_hDC, CAIRO_FORMAT_RGB24, GetSize().cx, GetSize().cy), GetSize().cx, GetSize().cy);
|
||||
else
|
||||
_cairo.SetSurface(cairo_win32_surface_create(_hDC), GetSize().cx, GetSize().cy);
|
||||
}
|
||||
}
|
||||
else if (reason == CLOSE && _hDC != NULL)
|
||||
{
|
||||
ReleaseDC(GetHWND(), _hDC);
|
||||
_hDC = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class CairoCtrl : public Ctrl
|
||||
{
|
||||
private:
|
||||
Drawing const *_drawing;
|
||||
Color const *_backgroundColor;
|
||||
Cairo _cairo;
|
||||
ImageBuffer _buffer;
|
||||
|
||||
void DoPaint()
|
||||
{
|
||||
if (!_cairo.HasContext())
|
||||
return;
|
||||
|
||||
CairoDraw draw(_cairo);
|
||||
|
||||
if (_drawing == NULL)
|
||||
{
|
||||
if (_backgroundColor != NULL)
|
||||
_cairo.Clear(*_backgroundColor);
|
||||
|
||||
CairoPaint(_cairo);
|
||||
UppPaint(draw);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cairo.Clear(_backgroundColor == NULL ? White() : *_backgroundColor);
|
||||
|
||||
Size drawingSize = _drawing->GetSize();
|
||||
Size size = GetSize();
|
||||
Size drawSize = size;
|
||||
int dx = 0, dy = 0;
|
||||
|
||||
if(drawingSize.cy * size.cx < size.cy * drawingSize.cx)
|
||||
{
|
||||
drawSize.cy = drawingSize.cy * size.cx / drawingSize.cx;
|
||||
dy = (size.cy - drawSize.cy) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawSize.cx = drawingSize.cx * size.cy / drawingSize.cy;
|
||||
dx = (size.cx - drawSize.cx) / 2;
|
||||
}
|
||||
|
||||
draw.Clipoff(dx, dy, drawSize.cx, drawSize.cy);
|
||||
draw.DrawDrawing(drawSize, *_drawing);
|
||||
draw.End();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Paint(Draw& draw)
|
||||
{
|
||||
if (GetSize() != _buffer.GetSize())
|
||||
{
|
||||
_buffer.Create(GetSize());
|
||||
_cairo.SetSurface(_buffer);
|
||||
}
|
||||
|
||||
if (_buffer.IsEmpty())
|
||||
return;
|
||||
|
||||
DoPaint();
|
||||
|
||||
Image i = _buffer;
|
||||
draw.DrawImage(0, 0, i);
|
||||
_buffer = i;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Called on paint events
|
||||
virtual void CairoPaint(Cairo &cairo) { WhenCairoPaint(cairo); }
|
||||
virtual void UppPaint(Draw &draw) { WhenPaint(draw); }
|
||||
|
||||
public:
|
||||
Callback1<Cairo &> WhenCairoPaint;
|
||||
Callback1<Draw &> WhenPaint;
|
||||
|
||||
CairoCtrl()
|
||||
: _drawing(NULL),
|
||||
_backgroundColor(NULL)
|
||||
{}
|
||||
|
||||
~CairoCtrl()
|
||||
{
|
||||
if (_backgroundColor != NULL)
|
||||
delete _backgroundColor;
|
||||
}
|
||||
|
||||
void Set(Drawing const * const drawing)
|
||||
{
|
||||
_drawing = drawing;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void Background(Color const &color)
|
||||
{
|
||||
if (_backgroundColor != NULL)
|
||||
delete _backgroundColor;
|
||||
|
||||
_backgroundColor = new Color(color);
|
||||
}
|
||||
|
||||
void SetDoubleBuffering(bool buffer = true) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
259
uppdev/plugin/cairo/CairoDraw.cpp
Normal file
259
uppdev/plugin/cairo/CairoDraw.cpp
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
#include "CairoDraw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void CairoDraw::BeginOp()
|
||||
{
|
||||
_cairo.Save();
|
||||
|
||||
_offsetStack.Add(actual_offset);
|
||||
_clipStack.Add(_actualClip);
|
||||
}
|
||||
|
||||
void CairoDraw::EndOp()
|
||||
{
|
||||
_cairo.Restore();
|
||||
|
||||
actual_offset = _offsetStack.Pop();
|
||||
_actualClip = _clipStack.Pop();
|
||||
}
|
||||
|
||||
void CairoDraw::OffsetOp(Point p)
|
||||
{
|
||||
Begin();
|
||||
|
||||
_cairo.Translate(p.x, p.y);
|
||||
|
||||
actual_offset += p;
|
||||
_actualClip -= p;
|
||||
}
|
||||
|
||||
bool CairoDraw::ClipOp(const Rect& r)
|
||||
{
|
||||
Begin();
|
||||
|
||||
_cairo.Rectangle(r.left, r.top, r.Width(), r.Height());
|
||||
_cairo.Clip();
|
||||
|
||||
_actualClip &= r;
|
||||
return !_actualClip.IsEmpty();
|
||||
}
|
||||
|
||||
bool CairoDraw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
Begin();
|
||||
|
||||
_cairo.Translate(r.left, r.top);
|
||||
|
||||
_cairo.Rectangle(0, 0, r.Width(), r.Height());
|
||||
_cairo.Clip();
|
||||
|
||||
actual_offset += r.TopLeft();
|
||||
_actualClip &= r;
|
||||
_actualClip -= r.TopLeft();
|
||||
return !_actualClip.IsEmpty();
|
||||
}
|
||||
|
||||
bool CairoDraw::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
_cairo.MoveTo(0, 0);
|
||||
_cairo.LineTo(_cairo.GetWidth(), 0);
|
||||
_cairo.LineTo(_cairo.GetWidth(), _cairo.GetHeight());
|
||||
_cairo.LineTo(0, _cairo.GetHeight());
|
||||
|
||||
_cairo.LineTo(0, r.bottom);
|
||||
_cairo.LineTo(r.right, r.bottom);
|
||||
_cairo.LineTo(r.right, r.top);
|
||||
_cairo.LineTo(r.left, r.top);
|
||||
_cairo.LineTo(r.left, r.bottom);
|
||||
|
||||
_cairo.LineTo(0, r.bottom);
|
||||
_cairo.ClosePath();
|
||||
|
||||
_cairo.Clip();
|
||||
|
||||
return !_actualClip.IsEmpty();
|
||||
}
|
||||
|
||||
bool CairoDraw::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
_cairo.Rectangle(r.left, r.top, r.Width(), r.Height());
|
||||
_cairo.Clip();
|
||||
|
||||
_actualClip &= r;
|
||||
return !_actualClip.IsEmpty();
|
||||
}
|
||||
|
||||
Rect CairoDraw::GetClipOp() const
|
||||
{
|
||||
return _actualClip;
|
||||
}
|
||||
|
||||
bool CairoDraw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CairoDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
_cairo.Rectangle(x, y, cx, cy);
|
||||
_cairo.SetSourceRGB(color);
|
||||
_cairo.Fill();
|
||||
}
|
||||
|
||||
void CairoDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
_cairo.Save();
|
||||
|
||||
cairo_t *context = _cairo.GetContext();
|
||||
ASSERT(context != NULL);
|
||||
|
||||
cairo_surface_t *imgSurface = cairo_image_surface_create_for_data((unsigned char *)&(img[0]->b),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
img.GetWidth(),
|
||||
img.GetHeight(),
|
||||
img.GetWidth() * 4);
|
||||
|
||||
_cairo.Translate(x, y);
|
||||
_cairo.Scale((double)cx / img.GetWidth(), (double)cy / img.GetHeight());
|
||||
cairo_set_source_surface(context, imgSurface, 0, 0);
|
||||
cairo_rectangle(context, 0, 0, cx, cy); //todo: src rect
|
||||
_cairo.Fill();
|
||||
cairo_surface_destroy(imgSurface);
|
||||
|
||||
_cairo.Restore();
|
||||
}
|
||||
|
||||
void CairoDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
if (width == 0) width = 1;
|
||||
|
||||
_cairo.SetLineCap(CAIRO_LINE_CAP_ROUND);
|
||||
_cairo.SetSourceRGB(color);
|
||||
_cairo.SetLineWidth(width);
|
||||
_cairo.MoveTo(x1 + 0.5, y1 + 0.5);
|
||||
_cairo.LineTo(x2 + 0.5, y2 + 0.5);
|
||||
_cairo.Stroke();
|
||||
}
|
||||
|
||||
void CairoDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
if (width == 0) width = 1;
|
||||
|
||||
for (int i = 0; i < count_count; i++)
|
||||
{
|
||||
ASSERT(counts[i] >= 1);
|
||||
_cairo.MoveTo(vertices->x + 0.5, vertices->y + 0.5);
|
||||
vertices++;
|
||||
|
||||
for (int j = 1; j < counts[i]; j++, vertices++)
|
||||
_cairo.LineTo(vertices->x + 0.5, vertices->y + 0.5);
|
||||
}
|
||||
|
||||
_cairo.SetLineCap(CAIRO_LINE_CAP_ROUND);
|
||||
_cairo.SetLineJoin(CAIRO_LINE_JOIN_ROUND);
|
||||
_cairo.SetLineWidth(width);
|
||||
_cairo.SetSourceRGB(color);
|
||||
_cairo.Stroke();
|
||||
}
|
||||
|
||||
void CairoDraw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc,
|
||||
Color color, int width, Color outline,
|
||||
uint64 pattern, Color doxor)
|
||||
{
|
||||
if (width == 0) width = 1;
|
||||
|
||||
for (int i = 0; i < scc; i++)
|
||||
{
|
||||
ASSERT(subpolygon_counts[i] >= 1);
|
||||
_cairo.MoveTo(vertices->x, vertices->y);
|
||||
vertices++;
|
||||
|
||||
for (int j = 1; j < subpolygon_counts[i]; j++, vertices++)
|
||||
_cairo.LineTo(vertices->x, vertices->y);
|
||||
|
||||
_cairo.ClosePath();
|
||||
}
|
||||
|
||||
_cairo.SetSourceRGB(color);
|
||||
_cairo.Fill(true);
|
||||
_cairo.SetLineCap(CAIRO_LINE_CAP_ROUND);
|
||||
_cairo.SetLineJoin(CAIRO_LINE_JOIN_ROUND);
|
||||
_cairo.SetLineWidth(width);
|
||||
_cairo.SetSourceRGB(outline);
|
||||
_cairo.Stroke();
|
||||
}
|
||||
|
||||
void CairoDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
if (pen == 0) pen = 1;
|
||||
|
||||
_cairo.Save();
|
||||
_cairo.Translate(r.left + (r.Width() / 2.0), r.top + (r.Height() / 2.0));
|
||||
_cairo.Scale(r.Width() / 2.0, r.Height() / 2.0);
|
||||
_cairo.Arc(0.0, 0.0, 1.0, 0.0, 2 * M_PI);
|
||||
_cairo.Restore();
|
||||
|
||||
_cairo.SetSourceRGB(color);
|
||||
|
||||
_cairo.Fill(pen != (int)Null);
|
||||
|
||||
if (pen != (int)Null)
|
||||
{
|
||||
_cairo.SetLineWidth(pen);
|
||||
_cairo.SetSourceRGB(pencolor);
|
||||
_cairo.Stroke();
|
||||
}
|
||||
}
|
||||
|
||||
void CairoDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
if (width == 0) width = 1;
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
||||
void CairoDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx)
|
||||
{
|
||||
cairo_t *context = _cairo.GetContext();
|
||||
ASSERT(context != NULL);
|
||||
|
||||
/*HFONT hFont = CreateFont(font.GetHeight() ? -abs(font.GetHeight()) : -12,
|
||||
font.GetWidth(), angle, angle, font.IsBold() ? FW_BOLD : FW_NORMAL,
|
||||
font.IsItalic(), font.IsUnderline(), font.IsStrikeout(),
|
||||
Font::GetFaceInfo(font.GetFace()) & Font::SYMBOLTYPE ? SYMBOL_CHARSET : DEFAULT_CHARSET,
|
||||
font.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
font.IsNonAntiAliased() ? NONANTIALIASED_QUALITY
|
||||
: DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH|FF_DONTCARE,
|
||||
Font::GetFaceName(font.GetFace())/*sFontFace().GetKey(font.GetFace())* /);
|
||||
|
||||
cairo_font_face_t *fontFace = cairo_win32_font_face_create_for_hfont(hFont);
|
||||
cairo_set_font_face(context, fontFace);*/
|
||||
cairo_set_font_size(context, font.GetHeight());
|
||||
|
||||
_cairo.Save();
|
||||
|
||||
_cairo.Translate(x, y + (font.GetHeight() ? abs(font.GetHeight()) : 12));
|
||||
_cairo.Rotate(angle * (-3.14159 / 1800.0));
|
||||
|
||||
_cairo.SetSourceRGB(ink);
|
||||
WString tempWString = text;
|
||||
cairo_show_text(context, tempWString.ToString());
|
||||
|
||||
_cairo.NewPath();
|
||||
|
||||
_cairo.Restore();
|
||||
|
||||
/*cairo_font_face_destroy(fontFace);*/
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
51
uppdev/plugin/cairo/CairoDraw.h
Normal file
51
uppdev/plugin/cairo/CairoDraw.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef _plugin_cairo_CairoDraw_h_
|
||||
#define _plugin_cairo_CairoDraw_h_
|
||||
|
||||
#include <Draw/Draw.h>
|
||||
#include "Cairo.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class CairoDraw : public Draw
|
||||
{
|
||||
private:
|
||||
Vector<Point> _offsetStack;
|
||||
Vector<Rect> _clipStack;
|
||||
Rect _actualClip;
|
||||
Cairo &_cairo;
|
||||
|
||||
public:
|
||||
CairoDraw(Cairo &cairo)
|
||||
: _cairo(cairo)
|
||||
{}
|
||||
|
||||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
virtual void OffsetOp(Point p);
|
||||
virtual bool ClipOp(const Rect& r);
|
||||
virtual bool ClipoffOp(const Rect& r);
|
||||
virtual bool ExcludeClipOp(const Rect& r);
|
||||
virtual bool IntersectClipOp(const Rect& r);
|
||||
virtual Rect GetClipOp() const;
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
|
||||
virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color);
|
||||
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
|
||||
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor);
|
||||
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc,
|
||||
Color color, int width, Color outline,
|
||||
uint64 pattern, Color doxor);
|
||||
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
|
||||
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
|
||||
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx);
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
185
uppdev/plugin/cairo/CairoPattern.h
Normal file
185
uppdev/plugin/cairo/CairoPattern.h
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#ifndef _plugin_cairo_CairoPattern_h_
|
||||
#define _plugin_cairo_CairoPattern_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
#include "lib/cairo.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#if 1
|
||||
#define CAIRO_METHOD_ENTER() ASSERT(_pattern != NULL)
|
||||
#define CAIRO_METHOD_LEAVE() { \
|
||||
cairo_status_t status = cairo_pattern_status(_pattern); \
|
||||
ASSERT_(status == CAIRO_STATUS_SUCCESS, cairo_status_to_string(status)); \
|
||||
}
|
||||
#else
|
||||
#define CAIRO_METHOD_ENTER()
|
||||
#define CAIRO_METHOD_LEAVE()
|
||||
#endif
|
||||
|
||||
class CairoPattern : public NoCopy /*abstract*/
|
||||
{
|
||||
protected:
|
||||
cairo_pattern_t *_pattern;
|
||||
|
||||
CairoPattern()
|
||||
: _pattern(NULL)
|
||||
{}
|
||||
|
||||
virtual ~CairoPattern()
|
||||
{
|
||||
if (_pattern != NULL)
|
||||
cairo_pattern_destroy(_pattern);
|
||||
}
|
||||
|
||||
public:
|
||||
cairo_pattern_t *GetPattern()
|
||||
{
|
||||
return _pattern;
|
||||
}
|
||||
|
||||
void SetExtend(cairo_extend_t extend)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_pattern_set_extend(_pattern, extend);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_extend ()
|
||||
|
||||
void SetFilter(cairo_filter_t filter)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_pattern_set_filter(_pattern, filter);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_filter ()
|
||||
//cairo_pattern_set_matrix ()
|
||||
//cairo_pattern_get_matrix ()
|
||||
//cairo_pattern_get_type ()
|
||||
};
|
||||
|
||||
class CairoGradient : public CairoPattern /*abstract*/
|
||||
{
|
||||
protected:
|
||||
CairoGradient() {}
|
||||
|
||||
public:
|
||||
void AddColorStopRGB(double offset, double r, double g, double b)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_pattern_add_color_stop_rgb(_pattern, offset, r, g, b);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void AddColorStopRGB(double offset, Color const &color)
|
||||
{
|
||||
AddColorStopRGB(offset, color.GetR() / 255.0, color.GetG() / 255.0, color.GetB() / 255.0);
|
||||
}
|
||||
|
||||
void AddColorStopRGBA(double offset, double r, double g, double b, double a)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_pattern_add_color_stop_rgba(_pattern, offset, r, g, b, a);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_color_stop_count ()
|
||||
//cairo_pattern_get_color_stop_rgba ()
|
||||
};
|
||||
|
||||
class CairoSolidPattern : public CairoPattern
|
||||
{
|
||||
public:
|
||||
CairoSolidPattern(double r, double g, double b) { SetRGB(r, g, b); }
|
||||
CairoSolidPattern(Color const &color) { SetRGB(color); }
|
||||
CairoSolidPattern(double r, double g, double b, double a) { SetRGBA(r, g, b, a); }
|
||||
|
||||
void SetRGB(double r, double g, double b)
|
||||
{
|
||||
if (_pattern != NULL)
|
||||
cairo_pattern_destroy(_pattern);
|
||||
|
||||
_pattern = cairo_pattern_create_rgb(r, g, b);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void SetRGB(Color const &color)
|
||||
{
|
||||
SetRGB(color.GetR() / 255.0, color.GetG() / 255.0, color.GetB() / 255.0);
|
||||
}
|
||||
|
||||
void SetRGBA(double r, double g, double b, double a)
|
||||
{
|
||||
if (_pattern != NULL)
|
||||
cairo_pattern_destroy(_pattern);
|
||||
|
||||
_pattern = cairo_pattern_create_rgba(r, g, b, a);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_rgba ()
|
||||
};
|
||||
|
||||
class CairoLinearGradient : public CairoGradient
|
||||
{
|
||||
public:
|
||||
CairoLinearGradient(double x0, double y0, double x1, double y1) { Set(x0, y0, x1, y1); }
|
||||
|
||||
void Set(double x0, double y0, double x1, double y1)
|
||||
{
|
||||
if (_pattern != NULL)
|
||||
cairo_pattern_destroy(_pattern);
|
||||
|
||||
_pattern = cairo_pattern_create_linear(x0, y0, x1, y1);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_linear_points ()
|
||||
};
|
||||
|
||||
class CairoRadialGradient : public CairoGradient
|
||||
{
|
||||
public:
|
||||
CairoRadialGradient(double cx0, double cy0, double radius0, double cx1, double cy1, double radius1)
|
||||
{
|
||||
Set(cx0, cy0, radius0, cx1, cy1, radius1);
|
||||
}
|
||||
|
||||
void Set(double cx0, double cy0, double radius0, double cx1, double cy1, double radius1)
|
||||
{
|
||||
if (_pattern != NULL)
|
||||
cairo_pattern_destroy(_pattern);
|
||||
|
||||
_pattern = cairo_pattern_create_radial(cx0, cy0, radius0, cx1, cy1, radius1);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_radial_circles ()
|
||||
};
|
||||
|
||||
class CairoSurfacePattern : public CairoPattern
|
||||
{
|
||||
public:
|
||||
CairoSurfacePattern(cairo_surface_t *surface) { Set(surface); }
|
||||
|
||||
void Set(cairo_surface_t *surface)
|
||||
{
|
||||
if (_pattern != NULL)
|
||||
cairo_pattern_destroy(_pattern);
|
||||
|
||||
_pattern = cairo_pattern_create_for_surface(surface);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
//cairo_pattern_get_surface ()
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#undef CAIRO_METHOD_ENTER
|
||||
#undef CAIRO_METHOD_LEAVE
|
||||
|
||||
#endif
|
||||
390
uppdev/plugin/cairo/CairoUpp.cpp
Normal file
390
uppdev/plugin/cairo/CairoUpp.cpp
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
#include "Cairo.h"
|
||||
|
||||
#include "CairoPattern.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Cairo::SetSurface(cairo_surface_t *surface, int width, int height)
|
||||
{
|
||||
ASSERT(surface != NULL);
|
||||
|
||||
DestroySurface();
|
||||
|
||||
_surface = surface;
|
||||
_context = cairo_create(_surface);
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
void Cairo::SetSurface(ImageBuffer &img)
|
||||
{
|
||||
ASSERT(img.IsEmpty() == false);
|
||||
|
||||
cairo_surface_t *surface = cairo_image_surface_create_for_data((unsigned char *)&(img[0]->b),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
img.GetSize().cx,
|
||||
img.GetSize().cy,
|
||||
img.GetSize().cx * 4);
|
||||
|
||||
SetSurface(surface, img.GetSize().cx, img.GetSize().cy);
|
||||
}
|
||||
|
||||
void Cairo::CreateSvgSurface(String const &filename, double widthInPoints, double heightInPoints)
|
||||
{
|
||||
SetSurface(cairo_svg_surface_create(filename, widthInPoints, heightInPoints), static_cast<int>(widthInPoints), static_cast<int>(heightInPoints));
|
||||
}
|
||||
|
||||
void Cairo::CreatePdfSurface(String const &filename, double widthInPoints, double heightInPoints)
|
||||
{
|
||||
SetSurface(cairo_pdf_surface_create(filename, widthInPoints, heightInPoints), static_cast<int>(widthInPoints), static_cast<int>(heightInPoints));
|
||||
}
|
||||
|
||||
#if 1
|
||||
#define CAIRO_METHOD_ENTER() ASSERT(_context != NULL)
|
||||
#define CAIRO_METHOD_LEAVE() { \
|
||||
cairo_status_t status = cairo_status(_context); \
|
||||
ASSERT_(status == CAIRO_STATUS_SUCCESS, cairo_status_to_string(status)); \
|
||||
}
|
||||
#else
|
||||
#define CAIRO_METHOD_ENTER()
|
||||
#define CAIRO_METHOD_LEAVE()
|
||||
#endif
|
||||
|
||||
void Cairo::Save()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_save(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Restore()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_restore(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::PushGroup()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_push_group(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::PopGroup()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_pop_group(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::PopGroupToSource()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_pop_group_to_source(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::SetSourceRGB(double r, double g, double b)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_source_rgb(_context, r, g, b);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::SetSourceRGB(Color const &color)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_source_rgb(_context, color.GetR() / 255.0, color.GetG() / 255.0, color.GetB() / 255.0);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::SetSourceRGBA(double r, double g, double b, double a)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_source_rgba(_context, r, g, b, a);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::SetSource(CairoPattern &pattern)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_source(_context, pattern.GetPattern());
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::SetAntialias(cairo_antialias_t antialias)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_antialias(_context, antialias);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
cairo_antialias_t Cairo::GetAntialias()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_antialias_t result = cairo_get_antialias(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetDash(double const * dashes, int numDashes, double offset)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_dash(_context, dashes, numDashes, offset);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::SetFillRule(cairo_fill_rule_t fillRule)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_fill_rule(_context, fillRule);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
cairo_fill_rule_t Cairo::GetFillRule()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_fill_rule_t result = cairo_get_fill_rule(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetLineCap(cairo_line_cap_t lineCap)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_line_cap(_context, lineCap);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
cairo_line_cap_t Cairo::GetLineCap()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_line_cap_t result = cairo_get_line_cap(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetLineJoin(cairo_line_join_t lineJoin)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_line_join(_context, lineJoin);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
cairo_line_join_t Cairo::GetLineJoin()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_line_join_t result = cairo_get_line_join(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetLineWidth(double width)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_line_width(_context, width);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
double Cairo::GetLineWidth()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
double result = cairo_get_line_width(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetMiterLimit(double limit)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_miter_limit(_context, limit);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
double Cairo::GetMiterLimit()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
double result = cairo_get_miter_limit(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetOperator(cairo_operator_t op)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_operator(_context, op);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
cairo_operator_t Cairo::GetOperator()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_operator_t result = cairo_get_operator(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::SetTolerance(double tolerance)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_set_tolerance(_context, tolerance);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
double Cairo::GetTolerance()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
double result = cairo_get_tolerance(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cairo::Clip(bool preserve)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
if (!preserve)
|
||||
cairo_clip(_context);
|
||||
else
|
||||
cairo_clip_preserve(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Fill(bool preserve)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
if (!preserve)
|
||||
cairo_fill(_context);
|
||||
else
|
||||
cairo_fill_preserve(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Paint(double alpha)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
if (alpha >= 1.0)
|
||||
cairo_paint(_context);
|
||||
else
|
||||
cairo_paint_with_alpha(_context, alpha);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Stroke(bool preserve)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
if (!preserve)
|
||||
cairo_stroke(_context);
|
||||
else
|
||||
cairo_stroke_preserve(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Translate(double tx, double ty)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_translate(_context, tx, ty);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Scale(double sx, double sy)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_scale(_context, sx, sy);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Rotate(double angle)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_rotate(_context, angle);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::IdentityMatrix()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_identity_matrix(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
Pointf Cairo::GetCurrentPoint()
|
||||
{
|
||||
Pointf p;
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_get_current_point(_context, &p.x, &p.y);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
return p;
|
||||
}
|
||||
|
||||
void Cairo::NewPath()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_new_path(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::ClosePath()
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_close_path(_context);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Arc(double xc, double yc, double radius, double angle1, double angle2)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_arc(_context, xc, yc, radius, angle1, angle2);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_curve_to(_context, x1, y1, x2, y2, x3, y3);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::LineTo(double x, double y)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_line_to(_context, x, y);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::MoveTo(double x, double y)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_move_to(_context, x, y);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::Rectangle(double x, double y, double width, double height)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_rectangle(_context, x, y, width, height);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::RelCurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_rel_curve_to(_context, x1, y1, x2, y2, x3, y3);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::RelLineTo(double x, double y)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_rel_line_to(_context, x, y);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
void Cairo::RelMoveTo(double x, double y)
|
||||
{
|
||||
CAIRO_METHOD_ENTER();
|
||||
cairo_rel_move_to(_context, x, y);
|
||||
CAIRO_METHOD_LEAVE();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
8
uppdev/plugin/cairo/cairo-version.h
Normal file
8
uppdev/plugin/cairo/cairo-version.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef CAIRO_VERSION_H
|
||||
#define CAIRO_VERSION_H
|
||||
|
||||
#define CAIRO_VERSION_MAJOR 1
|
||||
#define CAIRO_VERSION_MINOR 8
|
||||
#define CAIRO_VERSION_MICRO 0
|
||||
|
||||
#endif
|
||||
27
uppdev/plugin/cairo/cairo.upp
Normal file
27
uppdev/plugin/cairo/cairo.upp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
uses
|
||||
Core,
|
||||
plugin\png,
|
||||
plugin\pixman;
|
||||
|
||||
library(WIN32) "user32 gdi32 msimg32";
|
||||
|
||||
library(!WIN32) cairo;
|
||||
|
||||
options(WIN32) "-I\"./lib\" -I\"../pixman/lib\"";
|
||||
|
||||
options(WIN32) "-I\"C:/upp/uppsrc/plugin/z/lib\" -I\"C:/upp/uppsrc/plugin/png/lib\"";
|
||||
|
||||
options(WIN32) -D_CRT_SECURE_NO_WARNINGS;
|
||||
|
||||
file
|
||||
Cairo.h,
|
||||
CairoUpp.cpp,
|
||||
CairoPattern.h,
|
||||
CairoDraw.h,
|
||||
CairoDraw.cpp,
|
||||
CairoCtrl.h,
|
||||
cairolib.c,
|
||||
cairolibwin32.c,
|
||||
Cairo readonly separator,
|
||||
lib/cairo-features.h;
|
||||
|
||||
92
uppdev/plugin/cairo/cairolib.c
Normal file
92
uppdev/plugin/cairo/cairolib.c
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#ifdef flagWIN32
|
||||
|
||||
#undef CAIRO_VERSION_H
|
||||
#undef CAIRO_VERSION_MAJOR
|
||||
#undef CAIRO_VERSION_MINOR
|
||||
#undef CAIRO_VERSION_MICRO
|
||||
#include "lib/cairo-version.c"
|
||||
|
||||
#include "lib/cairo-analysis-surface.c"
|
||||
#include "lib/cairo-arc.c"
|
||||
#include "lib/cairo-array.c"
|
||||
#include "lib/cairo-atomic.c"
|
||||
#include "lib/cairo-base85-stream.c"
|
||||
#include "lib/cairo-bentley-ottmann.c"
|
||||
#include "lib/cairo-cache.c"
|
||||
|
||||
#undef _BSD_SOURCE
|
||||
#include "lib/cairo-cff-subset.c"
|
||||
|
||||
#include "lib/cairo-clip.c"
|
||||
#include "lib/cairo-color.c"
|
||||
//#include "lib/cairo-debug.c"
|
||||
#include "lib/cairo-deflate-stream.c"
|
||||
#include "lib/cairo-fixed.c"
|
||||
|
||||
#undef _BSD_SOURCE
|
||||
#include "lib/cairo-font-face.c"
|
||||
|
||||
#include "lib/cairo-font-face-twin.c"
|
||||
#include "lib/cairo-font-face-twin-data.c"
|
||||
#include "lib/cairo-font-options.c"
|
||||
#include "lib/cairo-freelist.c"
|
||||
#include "lib/cairo-gstate.c"
|
||||
#include "lib/cairo-hash.c"
|
||||
#include "lib/cairo-hull.c"
|
||||
#include "lib/cairo-image-surface.c"
|
||||
#include "lib/cairo-lzw.c"
|
||||
#include "lib/cairo-matrix.c"
|
||||
#include "lib/cairo-meta-surface.c"
|
||||
#include "lib/cairo-misc.c"
|
||||
#include "lib/cairo-mutex.c"
|
||||
|
||||
#undef _BSD_SOURCE
|
||||
#include "lib/cairo-output-stream.c"
|
||||
|
||||
#include "lib/cairo-paginated-surface.c"
|
||||
#include "lib/cairo-path-bounds.c"
|
||||
#include "lib/cairo-path-fill.c"
|
||||
#include "lib/cairo-path-fixed.c"
|
||||
#include "lib/cairo-path-stroke.c"
|
||||
#include "lib/cairo-path.c"
|
||||
#include "lib/cairo-pattern.c"
|
||||
#include "lib/cairo-pdf-operators.c"
|
||||
|
||||
#undef _BSD_SOURCE
|
||||
#include "lib/cairo-pdf-surface.c"
|
||||
|
||||
#include "lib/cairo-pen.c"
|
||||
#include "lib/cairo-polygon.c"
|
||||
#include "lib/cairo-png.c"
|
||||
#include "lib/cairo-rectangle.c"
|
||||
#include "lib/cairo-region.c"
|
||||
#include "lib/cairo-scaled-font-subsets.c"
|
||||
#include "lib/cairo-scaled-font.c"
|
||||
#include "lib/cairo-skiplist.c"
|
||||
#include "lib/cairo-slope.c"
|
||||
#include "lib/cairo-spline.c"
|
||||
#include "lib/cairo-stroke-style.c"
|
||||
#include "lib/cairo-surface-fallback.c"
|
||||
#include "lib/cairo-surface.c"
|
||||
#include "lib/cairo-svg-surface.c"
|
||||
#include "lib/cairo-traps.c"
|
||||
#include "lib/cairo-truetype-subset.c"
|
||||
#include "lib/cairo-type1-fallback.c"
|
||||
#include "lib/cairo-type3-glyph-surface.c"
|
||||
#include "lib/cairo-unicode.c"
|
||||
#include "lib/cairo-user-font.c"
|
||||
#include "lib/cairo-wideint.c"
|
||||
#include "lib/cairo.c"
|
||||
|
||||
// files that would be needed if you want to compile for linux.
|
||||
// currently we just use the cairo library from the system
|
||||
/*
|
||||
#include "lib/cairo-ft-font.c"
|
||||
#include "lib/cairo-xlib-screen.c"
|
||||
#include "lib/cairo-xlib-surface.c"
|
||||
#include "lib/cairo-xlib-visual.c"
|
||||
#include "lib/cairo-type1-subset.c"
|
||||
#include "lib/cairo-xlib-display.c"
|
||||
*/
|
||||
|
||||
#endif
|
||||
8
uppdev/plugin/cairo/cairolibwin32.c
Normal file
8
uppdev/plugin/cairo/cairolibwin32.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifdef flagWIN32
|
||||
|
||||
//#include "lib/cairo-win32.c"
|
||||
#include "lib/cairo-win32-font.c"
|
||||
#include "lib/cairo-win32-printing-surface.c"
|
||||
#include "lib/cairo-win32-surface.c"
|
||||
|
||||
#endif
|
||||
6
uppdev/plugin/cairo/init
Normal file
6
uppdev/plugin/cairo/init
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _plugin_cairo_icpp_init_stub
|
||||
#define _plugin_cairo_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#include "plugin\png/init"
|
||||
#include "plugin\pixman/init"
|
||||
#endif
|
||||
76
uppdev/plugin/cairo/lib/cairo-analysis-surface-private.h
Normal file
76
uppdev/plugin/cairo/lib/cairo-analysis-surface-private.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Packard
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_ANALYSIS_SURFACE_H
|
||||
#define CAIRO_ANALYSIS_SURFACE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_analysis_surface_create (cairo_surface_t *target,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_private void
|
||||
_cairo_analysis_surface_set_ctm (cairo_surface_t *surface,
|
||||
cairo_matrix_t *ctm);
|
||||
|
||||
cairo_private void
|
||||
_cairo_analysis_surface_get_ctm (cairo_surface_t *surface,
|
||||
cairo_matrix_t *ctm);
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_analysis_surface_has_supported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_analysis_surface_has_unsupported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private void
|
||||
_cairo_analysis_surface_get_bounding_box (cairo_surface_t *surface,
|
||||
cairo_box_t *bbox);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
|
||||
cairo_int_status_t status_b);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_null_surface_create (cairo_content_t content);
|
||||
|
||||
#endif /* CAIRO_ANALYSIS_SURFACE_H */
|
||||
988
uppdev/plugin/cairo/lib/cairo-analysis-surface.c
Normal file
988
uppdev/plugin/cairo/lib/cairo-analysis-surface.c
Normal file
|
|
@ -0,0 +1,988 @@
|
|||
/*
|
||||
* Copyright © 2006 Keith Packard
|
||||
* Copyright © 2007 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Packard
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
#include "cairo-paginated-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
|
||||
typedef struct {
|
||||
cairo_surface_t base;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
cairo_surface_t *target;
|
||||
|
||||
cairo_bool_t first_op;
|
||||
cairo_bool_t has_supported;
|
||||
cairo_bool_t has_unsupported;
|
||||
|
||||
cairo_region_t supported_region;
|
||||
cairo_region_t fallback_region;
|
||||
cairo_rectangle_int_t current_clip;
|
||||
cairo_box_t page_bbox;
|
||||
|
||||
cairo_bool_t has_ctm;
|
||||
cairo_matrix_t ctm;
|
||||
|
||||
} cairo_analysis_surface_t;
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
|
||||
cairo_int_status_t status_b)
|
||||
{
|
||||
/* fatal errors should be checked and propagated at source */
|
||||
assert (! _cairo_status_is_error (status_a));
|
||||
assert (! _cairo_status_is_error (status_b));
|
||||
|
||||
/* return the most important status */
|
||||
if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
|
||||
status_b == CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (status_a == CAIRO_INT_STATUS_IMAGE_FALLBACK ||
|
||||
status_b == CAIRO_INT_STATUS_IMAGE_FALLBACK)
|
||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
|
||||
if (status_a == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN ||
|
||||
status_b == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||
return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
|
||||
|
||||
if (status_a == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
|
||||
status_b == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
|
||||
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
||||
|
||||
/* at this point we have checked all the valid internal codes, so... */
|
||||
assert (status_a == CAIRO_STATUS_SUCCESS &&
|
||||
status_b == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
cairo_surface_t *analysis = &surface->base;
|
||||
cairo_surface_pattern_t *surface_pattern;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t old_has_ctm;
|
||||
cairo_matrix_t old_ctm, p2d;
|
||||
cairo_rectangle_int_t old_clip;
|
||||
cairo_rectangle_int_t meta_extents;
|
||||
int old_width;
|
||||
int old_height;
|
||||
|
||||
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
|
||||
surface_pattern = (cairo_surface_pattern_t *) pattern;
|
||||
assert (_cairo_surface_is_meta (surface_pattern->surface));
|
||||
|
||||
old_width = surface->width;
|
||||
old_height = surface->height;
|
||||
old_clip = surface->current_clip;
|
||||
status = _cairo_surface_get_extents (surface_pattern->surface, &meta_extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
surface->width = meta_extents.width;
|
||||
surface->height = meta_extents.height;
|
||||
surface->current_clip.x = 0;
|
||||
surface->current_clip.y = 0;
|
||||
surface->current_clip.width = surface->width;
|
||||
surface->current_clip.height = surface->height;
|
||||
old_ctm = surface->ctm;
|
||||
old_has_ctm = surface->has_ctm;
|
||||
p2d = pattern->matrix;
|
||||
status = cairo_matrix_invert (&p2d);
|
||||
/* _cairo_pattern_set_matrix guarantees invertibility */
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
|
||||
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
|
||||
|
||||
status = _cairo_meta_surface_replay_and_create_regions (surface_pattern->surface,
|
||||
analysis);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = analysis->status;
|
||||
|
||||
surface->ctm = old_ctm;
|
||||
surface->has_ctm = old_has_ctm;
|
||||
surface->current_clip = old_clip;
|
||||
surface->width = old_width;
|
||||
surface->height = old_height;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_add_operation (cairo_analysis_surface_t *surface,
|
||||
cairo_rectangle_int_t *rect,
|
||||
cairo_int_status_t backend_status)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_box_t bbox;
|
||||
|
||||
if (rect->width == 0 || rect->height == 0) {
|
||||
/* Even though the operation is not visible we must be careful
|
||||
* to not allow unsupported operations to be replayed to the
|
||||
* backend during CAIRO_PAGINATED_MODE_RENDER */
|
||||
if (backend_status == CAIRO_STATUS_SUCCESS ||
|
||||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_box_from_rectangle (&bbox, rect);
|
||||
|
||||
if (surface->has_ctm) {
|
||||
|
||||
_cairo_matrix_transform_bounding_box_fixed (&surface->ctm, &bbox, NULL);
|
||||
|
||||
if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
|
||||
/* Even though the operation is not visible we must be
|
||||
* careful to not allow unsupported operations to be
|
||||
* replayed to the backend during
|
||||
* CAIRO_PAGINATED_MODE_RENDER */
|
||||
if (backend_status == CAIRO_STATUS_SUCCESS ||
|
||||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_box_round_to_rectangle (&bbox, rect);
|
||||
}
|
||||
|
||||
if (surface->first_op) {
|
||||
surface->first_op = FALSE;
|
||||
surface->page_bbox = bbox;
|
||||
} else {
|
||||
if (bbox.p1.x < surface->page_bbox.p1.x)
|
||||
surface->page_bbox.p1.x = bbox.p1.x;
|
||||
if (bbox.p1.y < surface->page_bbox.p1.y)
|
||||
surface->page_bbox.p1.y = bbox.p1.y;
|
||||
if (bbox.p2.x > surface->page_bbox.p2.x)
|
||||
surface->page_bbox.p2.x = bbox.p2.x;
|
||||
if (bbox.p2.y > surface->page_bbox.p2.y)
|
||||
surface->page_bbox.p2.y = bbox.p2.y;
|
||||
}
|
||||
|
||||
/* If the operation is completely enclosed within the fallback
|
||||
* region there is no benefit in emitting a native operation as
|
||||
* the fallback image will be painted on top.
|
||||
*/
|
||||
if (_cairo_region_contains_rectangle (&surface->fallback_region, rect) == PIXMAN_REGION_IN)
|
||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) {
|
||||
/* A status of CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY indicates
|
||||
* that the backend only supports this operation if the
|
||||
* transparency removed. If the extents of this operation does
|
||||
* not intersect any other native operation, the operation is
|
||||
* natively supported and the backend will blend the
|
||||
* transparency into the white background.
|
||||
*/
|
||||
if (_cairo_region_contains_rectangle (&surface->supported_region, rect) == PIXMAN_REGION_OUT)
|
||||
backend_status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (backend_status == CAIRO_STATUS_SUCCESS) {
|
||||
/* Add the operation to the supported region. Operations in
|
||||
* this region will be emitted as native operations.
|
||||
*/
|
||||
surface->has_supported = TRUE;
|
||||
status = _cairo_region_union_rect (&surface->supported_region,
|
||||
&surface->supported_region,
|
||||
rect);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Add the operation to the unsupported region. This region will
|
||||
* be painted as an image after all native operations have been
|
||||
* emitted.
|
||||
*/
|
||||
surface->has_unsupported = TRUE;
|
||||
status = _cairo_region_union_rect (&surface->fallback_region,
|
||||
&surface->fallback_region,
|
||||
rect);
|
||||
|
||||
/* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate
|
||||
* unsupported operations to the meta surface as using
|
||||
* CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to
|
||||
* invoke the cairo-surface-fallback path then return
|
||||
* CAIRO_STATUS_SUCCESS.
|
||||
*/
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_analysis_surface_finish (void *abstract_surface)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
_cairo_region_fini (&surface->supported_region);
|
||||
_cairo_region_fini (&surface->fallback_region);
|
||||
|
||||
cairo_surface_destroy (surface->target);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
double x1, y1, x2, y2;
|
||||
cairo_rectangle_int_t extent;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
if (path == NULL) {
|
||||
surface->current_clip.x = 0;
|
||||
surface->current_clip.y = 0;
|
||||
surface->current_clip.width = surface->width;
|
||||
surface->current_clip.height = surface->height;
|
||||
} else {
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_path_fixed_bounds (path, &x1, &y1, &x2, &y2, tolerance);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
extent.x = floor (x1);
|
||||
extent.y = floor (y1);
|
||||
extent.width = ceil (x2) - extent.x;
|
||||
extent.height = ceil (y2) - extent.y;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&surface->current_clip, &extent);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status, backend_status;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
if (!surface->target->backend->paint)
|
||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
backend_status = (*surface->target->backend->paint) (surface->target, op,
|
||||
source);
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
||||
|
||||
status = _add_operation (surface, &extents, backend_status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_int_status_t status, backend_status;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
if (!surface->target->backend->mask)
|
||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
backend_status = (*surface->target->backend->mask) (surface->target, op,
|
||||
source, mask);
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) {
|
||||
cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source;
|
||||
if (_cairo_surface_is_meta (surface_pattern->surface)) {
|
||||
backend_source_status =
|
||||
_analyze_meta_surface_pattern (surface, source);
|
||||
if (_cairo_status_is_error (backend_source_status))
|
||||
return backend_source_status;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
|
||||
if (_cairo_surface_is_meta (surface_pattern->surface)) {
|
||||
backend_mask_status =
|
||||
_analyze_meta_surface_pattern (surface, mask);
|
||||
if (_cairo_status_is_error (backend_mask_status))
|
||||
return backend_mask_status;
|
||||
}
|
||||
}
|
||||
|
||||
backend_status =
|
||||
_cairo_analysis_surface_merge_status (backend_source_status,
|
||||
backend_mask_status);
|
||||
}
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_rectangle_int_t mask_extents;
|
||||
|
||||
status = _cairo_pattern_get_extents (mask, &mask_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
||||
}
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
||||
|
||||
status = _add_operation (surface, &extents, backend_status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status, backend_status;
|
||||
cairo_traps_t traps;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
if (!surface->target->backend->stroke)
|
||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
backend_status = (*surface->target->backend->stroke) (surface->target, op,
|
||||
source, path, style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_box_t box;
|
||||
|
||||
_cairo_box_from_rectangle (&box, &extents);
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
_cairo_traps_limit (&traps, &box);
|
||||
status = _cairo_path_fixed_stroke_to_traps (path,
|
||||
style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance,
|
||||
&traps);
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_traps_extents (&traps, &box);
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
_cairo_box_round_to_rectangle (&box, &extents);
|
||||
}
|
||||
|
||||
status = _add_operation (surface, &extents, backend_status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status, backend_status;
|
||||
cairo_traps_t traps;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
if (!surface->target->backend->fill)
|
||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
backend_status = (*surface->target->backend->fill) (surface->target, op,
|
||||
source, path, fill_rule,
|
||||
tolerance, antialias);
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_box_t box;
|
||||
|
||||
_cairo_box_from_rectangle (&box, &extents);
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
_cairo_traps_limit (&traps, &box);
|
||||
status = _cairo_path_fixed_fill_to_traps (path,
|
||||
fill_rule,
|
||||
tolerance,
|
||||
&traps);
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_traps_extents (&traps, &box);
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
_cairo_box_round_to_rectangle (&box, &extents);
|
||||
}
|
||||
|
||||
status = _add_operation (surface, &extents, backend_status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
int *remaining_glyphs)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status, backend_status;
|
||||
cairo_rectangle_int_t extents, glyph_extents;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
/* Adapted from _cairo_surface_show_glyphs */
|
||||
if (surface->target->backend->show_glyphs)
|
||||
backend_status = (*surface->target->backend->show_glyphs) (surface->target, op,
|
||||
source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font,
|
||||
remaining_glyphs);
|
||||
else if (surface->target->backend->show_text_glyphs)
|
||||
backend_status = surface->target->backend->show_text_glyphs (surface->target, op,
|
||||
source,
|
||||
NULL, 0,
|
||||
glyphs, num_glyphs,
|
||||
NULL, 0,
|
||||
FALSE,
|
||||
scaled_font);
|
||||
else
|
||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||
glyphs,
|
||||
num_glyphs,
|
||||
&glyph_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
|
||||
}
|
||||
|
||||
status = _add_operation (surface, &extents, backend_status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_analysis_surface_has_show_text_glyphs (void *abstract_surface)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
|
||||
return cairo_surface_has_show_text_glyphs (surface->target);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
const cairo_text_cluster_t *clusters,
|
||||
int num_clusters,
|
||||
cairo_text_cluster_flags_t cluster_flags,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status, backend_status;
|
||||
cairo_rectangle_int_t extents, glyph_extents;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
/* Adapted from _cairo_surface_show_glyphs */
|
||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (surface->target->backend->show_text_glyphs)
|
||||
backend_status = surface->target->backend->show_text_glyphs (surface->target, op,
|
||||
source,
|
||||
utf8, utf8_len,
|
||||
glyphs, num_glyphs,
|
||||
clusters, num_clusters, cluster_flags,
|
||||
scaled_font);
|
||||
if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED && surface->target->backend->show_glyphs) {
|
||||
int remaining_glyphs = num_glyphs;
|
||||
backend_status = surface->target->backend->show_glyphs (surface->target, op,
|
||||
source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font,
|
||||
&remaining_glyphs);
|
||||
glyphs += num_glyphs - remaining_glyphs;
|
||||
num_glyphs = remaining_glyphs;
|
||||
if (remaining_glyphs == 0)
|
||||
backend_status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||
glyphs,
|
||||
num_glyphs,
|
||||
&glyph_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
|
||||
}
|
||||
|
||||
status = _add_operation (surface, &extents, backend_status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
|
||||
NULL, /* create_similar */
|
||||
_cairo_analysis_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
_cairo_analysis_surface_intersect_clip_path,
|
||||
_cairo_analysis_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
_cairo_analysis_surface_paint,
|
||||
_cairo_analysis_surface_mask,
|
||||
_cairo_analysis_surface_stroke,
|
||||
_cairo_analysis_surface_fill,
|
||||
_cairo_analysis_surface_show_glyphs,
|
||||
NULL, /* snapshot */
|
||||
NULL, /* is_similar */
|
||||
NULL, /* reset */
|
||||
NULL, /* fill_stroke */
|
||||
NULL, /* create_solid_pattern_surface */
|
||||
_cairo_analysis_surface_has_show_text_glyphs,
|
||||
_cairo_analysis_surface_show_text_glyphs
|
||||
};
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_analysis_surface_create (cairo_surface_t *target,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_analysis_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
|
||||
status = target->status;
|
||||
if (status)
|
||||
return _cairo_surface_create_in_error (status);
|
||||
|
||||
surface = malloc (sizeof (cairo_analysis_surface_t));
|
||||
if (surface == NULL)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
|
||||
/* I believe the content type here is truly arbitrary. I'm quite
|
||||
* sure nothing will ever use this value. */
|
||||
_cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
cairo_matrix_init_identity (&surface->ctm);
|
||||
surface->has_ctm = FALSE;
|
||||
|
||||
surface->target = cairo_surface_reference (target);
|
||||
surface->first_op = TRUE;
|
||||
surface->has_supported = FALSE;
|
||||
surface->has_unsupported = FALSE;
|
||||
|
||||
surface->page_bbox.p1.x = 0;
|
||||
surface->page_bbox.p1.y = 0;
|
||||
surface->page_bbox.p2.x = 0;
|
||||
surface->page_bbox.p2.y = 0;
|
||||
|
||||
_cairo_region_init (&surface->supported_region);
|
||||
_cairo_region_init (&surface->fallback_region);
|
||||
|
||||
if (width == -1 && height == -1) {
|
||||
surface->current_clip.x = CAIRO_RECT_INT_MIN;
|
||||
surface->current_clip.y = CAIRO_RECT_INT_MIN;
|
||||
surface->current_clip.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
||||
surface->current_clip.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
||||
} else {
|
||||
surface->current_clip.x = 0;
|
||||
surface->current_clip.y = 0;
|
||||
surface->current_clip.width = width;
|
||||
surface->current_clip.height = height;
|
||||
}
|
||||
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface,
|
||||
cairo_matrix_t *ctm)
|
||||
{
|
||||
cairo_analysis_surface_t *surface;
|
||||
|
||||
if (abstract_surface->status)
|
||||
return;
|
||||
|
||||
surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
surface->ctm = *ctm;
|
||||
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_analysis_surface_get_ctm (cairo_surface_t *abstract_surface,
|
||||
cairo_matrix_t *ctm)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
*ctm = surface->ctm;
|
||||
}
|
||||
|
||||
|
||||
cairo_region_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
return &surface->supported_region;
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
return &surface->fallback_region;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_analysis_surface_has_supported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
return surface->has_supported;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
return surface->has_unsupported;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_analysis_surface_get_bounding_box (cairo_surface_t *abstract_surface,
|
||||
cairo_box_t *bbox)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
*bbox = surface->page_bbox;
|
||||
}
|
||||
|
||||
/* null surface type: a surface that does nothing (has no side effects, yay!) */
|
||||
|
||||
static cairo_int_status_t
|
||||
_return_success (void)
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* These typedefs are just to silence the compiler... */
|
||||
typedef cairo_int_status_t
|
||||
(*_set_clip_region_func) (void *surface,
|
||||
cairo_region_t *region);
|
||||
typedef cairo_int_status_t
|
||||
(*_paint_func) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source);
|
||||
|
||||
typedef cairo_int_status_t
|
||||
(*_mask_func) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask);
|
||||
|
||||
typedef cairo_int_status_t
|
||||
(*_stroke_func) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
typedef cairo_int_status_t
|
||||
(*_fill_func) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
typedef cairo_int_status_t
|
||||
(*_show_glyphs_func) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
int *remaining_glyphs);
|
||||
|
||||
static const cairo_surface_backend_t cairo_null_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
||||
|
||||
NULL, /* create_similar */
|
||||
NULL, /* finish */
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
(_set_clip_region_func) _return_success, /* set_clip_region */
|
||||
NULL, /* intersect_clip_path */
|
||||
NULL, /* get_extents */
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
(_paint_func) _return_success, /* paint */
|
||||
(_mask_func) _return_success, /* mask */
|
||||
(_stroke_func) _return_success, /* stroke */
|
||||
(_fill_func) _return_success, /* fill */
|
||||
(_show_glyphs_func) _return_success, /* show_glyphs */
|
||||
NULL, /* snapshot */
|
||||
NULL, /* is_similar */
|
||||
NULL, /* reset */
|
||||
NULL, /* fill_stroke */
|
||||
NULL, /* create_solid_pattern_surface */
|
||||
NULL, /* has_show_text_glyphs */
|
||||
NULL /* show_text_glyphs */
|
||||
};
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_null_surface_create (cairo_content_t content)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = malloc (sizeof (cairo_surface_t));
|
||||
if (surface == NULL) {
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
_cairo_surface_init (surface, &cairo_null_surface_backend, content);
|
||||
|
||||
return surface;
|
||||
}
|
||||
57
uppdev/plugin/cairo/lib/cairo-arc-private.h
Normal file
57
uppdev/plugin/cairo/lib/cairo-arc-private.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_ARC_PRIVATE_H
|
||||
#define CAIRO_ARC_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
cairo_private void
|
||||
_cairo_arc_path (cairo_t *cr,
|
||||
double xc,
|
||||
double yc,
|
||||
double radius,
|
||||
double angle1,
|
||||
double angle2);
|
||||
|
||||
cairo_private void
|
||||
_cairo_arc_path_negative (cairo_t *cr,
|
||||
double xc,
|
||||
double yc,
|
||||
double radius,
|
||||
double angle1,
|
||||
double angle2);
|
||||
|
||||
#endif /* CAIRO_ARC_PRIVATE_H */
|
||||
292
uppdev/plugin/cairo/lib/cairo-arc.c
Normal file
292
uppdev/plugin/cairo/lib/cairo-arc.c
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-arc-private.h"
|
||||
|
||||
/* Spline deviation from the circle in radius would be given by:
|
||||
|
||||
error = sqrt (x**2 + y**2) - 1
|
||||
|
||||
A simpler error function to work with is:
|
||||
|
||||
e = x**2 + y**2 - 1
|
||||
|
||||
From "Good approximation of circles by curvature-continuous Bezier
|
||||
curves", Tor Dokken and Morten Daehlen, Computer Aided Geometric
|
||||
Design 8 (1990) 22-41, we learn:
|
||||
|
||||
abs (max(e)) = 4/27 * sin**6(angle/4) / cos**2(angle/4)
|
||||
|
||||
and
|
||||
abs (error) =~ 1/2 * e
|
||||
|
||||
Of course, this error value applies only for the particular spline
|
||||
approximation that is used in _cairo_gstate_arc_segment.
|
||||
*/
|
||||
static double
|
||||
_arc_error_normalized (double angle)
|
||||
{
|
||||
return 2.0/27.0 * pow (sin (angle / 4), 6) / pow (cos (angle / 4), 2);
|
||||
}
|
||||
|
||||
static double
|
||||
_arc_max_angle_for_tolerance_normalized (double tolerance)
|
||||
{
|
||||
double angle, error;
|
||||
int i;
|
||||
|
||||
/* Use table lookup to reduce search time in most cases. */
|
||||
struct {
|
||||
double angle;
|
||||
double error;
|
||||
} table[] = {
|
||||
{ M_PI / 1.0, 0.0185185185185185036127 },
|
||||
{ M_PI / 2.0, 0.000272567143730179811158 },
|
||||
{ M_PI / 3.0, 2.38647043651461047433e-05 },
|
||||
{ M_PI / 4.0, 4.2455377443222443279e-06 },
|
||||
{ M_PI / 5.0, 1.11281001494389081528e-06 },
|
||||
{ M_PI / 6.0, 3.72662000942734705475e-07 },
|
||||
{ M_PI / 7.0, 1.47783685574284411325e-07 },
|
||||
{ M_PI / 8.0, 6.63240432022601149057e-08 },
|
||||
{ M_PI / 9.0, 3.2715520137536980553e-08 },
|
||||
{ M_PI / 10.0, 1.73863223499021216974e-08 },
|
||||
{ M_PI / 11.0, 9.81410988043554039085e-09 },
|
||||
};
|
||||
int table_size = ARRAY_LENGTH (table);
|
||||
|
||||
for (i = 0; i < table_size; i++)
|
||||
if (table[i].error < tolerance)
|
||||
return table[i].angle;
|
||||
|
||||
++i;
|
||||
do {
|
||||
angle = M_PI / i++;
|
||||
error = _arc_error_normalized (angle);
|
||||
} while (error > tolerance);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
static int
|
||||
_arc_segments_needed (double angle,
|
||||
double radius,
|
||||
cairo_matrix_t *ctm,
|
||||
double tolerance)
|
||||
{
|
||||
double major_axis, max_angle;
|
||||
|
||||
/* the error is amplified by at most the length of the
|
||||
* major axis of the circle; see cairo-pen.c for a more detailed analysis
|
||||
* of this. */
|
||||
major_axis = _cairo_matrix_transformed_circle_major_axis (ctm, radius);
|
||||
max_angle = _arc_max_angle_for_tolerance_normalized (tolerance / major_axis);
|
||||
|
||||
return (int) ceil (angle / max_angle);
|
||||
}
|
||||
|
||||
/* We want to draw a single spline approximating a circular arc radius
|
||||
R from angle A to angle B. Since we want a symmetric spline that
|
||||
matches the endpoints of the arc in position and slope, we know
|
||||
that the spline control points must be:
|
||||
|
||||
(R * cos(A), R * sin(A))
|
||||
(R * cos(A) - h * sin(A), R * sin(A) + h * cos (A))
|
||||
(R * cos(B) + h * sin(B), R * sin(B) - h * cos (B))
|
||||
(R * cos(B), R * sin(B))
|
||||
|
||||
for some value of h.
|
||||
|
||||
"Approximation of circular arcs by cubic poynomials", Michael
|
||||
Goldapp, Computer Aided Geometric Design 8 (1991) 227-238, provides
|
||||
various values of h along with error analysis for each.
|
||||
|
||||
From that paper, a very practical value of h is:
|
||||
|
||||
h = 4/3 * tan(angle/4)
|
||||
|
||||
This value does not give the spline with minimal error, but it does
|
||||
provide a very good approximation, (6th-order convergence), and the
|
||||
error expression is quite simple, (see the comment for
|
||||
_arc_error_normalized).
|
||||
*/
|
||||
static void
|
||||
_cairo_arc_segment (cairo_t *cr,
|
||||
double xc,
|
||||
double yc,
|
||||
double radius,
|
||||
double angle_A,
|
||||
double angle_B)
|
||||
{
|
||||
double r_sin_A, r_cos_A;
|
||||
double r_sin_B, r_cos_B;
|
||||
double h;
|
||||
|
||||
r_sin_A = radius * sin (angle_A);
|
||||
r_cos_A = radius * cos (angle_A);
|
||||
r_sin_B = radius * sin (angle_B);
|
||||
r_cos_B = radius * cos (angle_B);
|
||||
|
||||
h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0);
|
||||
|
||||
cairo_curve_to (cr,
|
||||
xc + r_cos_A - h * r_sin_A,
|
||||
yc + r_sin_A + h * r_cos_A,
|
||||
xc + r_cos_B + h * r_sin_B,
|
||||
yc + r_sin_B - h * r_cos_B,
|
||||
xc + r_cos_B,
|
||||
yc + r_sin_B);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_arc_in_direction (cairo_t *cr,
|
||||
double xc,
|
||||
double yc,
|
||||
double radius,
|
||||
double angle_min,
|
||||
double angle_max,
|
||||
cairo_direction_t dir)
|
||||
{
|
||||
if (cairo_status (cr))
|
||||
return;
|
||||
|
||||
while (angle_max - angle_min > 4 * M_PI)
|
||||
angle_max -= 2 * M_PI;
|
||||
|
||||
/* Recurse if drawing arc larger than pi */
|
||||
if (angle_max - angle_min > M_PI) {
|
||||
double angle_mid = angle_min + (angle_max - angle_min) / 2.0;
|
||||
if (dir == CAIRO_DIRECTION_FORWARD) {
|
||||
_cairo_arc_in_direction (cr, xc, yc, radius,
|
||||
angle_min, angle_mid,
|
||||
dir);
|
||||
|
||||
_cairo_arc_in_direction (cr, xc, yc, radius,
|
||||
angle_mid, angle_max,
|
||||
dir);
|
||||
} else {
|
||||
_cairo_arc_in_direction (cr, xc, yc, radius,
|
||||
angle_mid, angle_max,
|
||||
dir);
|
||||
|
||||
_cairo_arc_in_direction (cr, xc, yc, radius,
|
||||
angle_min, angle_mid,
|
||||
dir);
|
||||
}
|
||||
} else if (angle_max != angle_min) {
|
||||
cairo_matrix_t ctm;
|
||||
int i, segments;
|
||||
double angle, angle_step;
|
||||
|
||||
cairo_get_matrix (cr, &ctm);
|
||||
segments = _arc_segments_needed (angle_max - angle_min,
|
||||
radius, &ctm,
|
||||
cairo_get_tolerance (cr));
|
||||
angle_step = (angle_max - angle_min) / (double) segments;
|
||||
|
||||
if (dir == CAIRO_DIRECTION_FORWARD) {
|
||||
angle = angle_min;
|
||||
} else {
|
||||
angle = angle_max;
|
||||
angle_step = - angle_step;
|
||||
}
|
||||
|
||||
for (i = 0; i < segments; i++, angle += angle_step) {
|
||||
_cairo_arc_segment (cr, xc, yc,
|
||||
radius,
|
||||
angle,
|
||||
angle + angle_step);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_arc_path
|
||||
* @cr: a cairo context
|
||||
* @xc: X position of the center of the arc
|
||||
* @yc: Y position of the center of the arc
|
||||
* @radius: the radius of the arc
|
||||
* @angle1: the start angle, in radians
|
||||
* @angle2: the end angle, in radians
|
||||
*
|
||||
* Compute a path for the given arc and append it onto the current
|
||||
* path within @cr. The arc will be accurate within the current
|
||||
* tolerance and given the current transformation.
|
||||
**/
|
||||
void
|
||||
_cairo_arc_path (cairo_t *cr,
|
||||
double xc,
|
||||
double yc,
|
||||
double radius,
|
||||
double angle1,
|
||||
double angle2)
|
||||
{
|
||||
_cairo_arc_in_direction (cr, xc, yc,
|
||||
radius,
|
||||
angle1, angle2,
|
||||
CAIRO_DIRECTION_FORWARD);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_arc_path_negative:
|
||||
* @xc: X position of the center of the arc
|
||||
* @yc: Y position of the center of the arc
|
||||
* @radius: the radius of the arc
|
||||
* @angle1: the start angle, in radians
|
||||
* @angle2: the end angle, in radians
|
||||
* @ctm: the current transformation matrix
|
||||
* @tolerance: the current tolerance value
|
||||
* @path: the path onto which the arc will be appended
|
||||
*
|
||||
* Compute a path for the given arc (defined in the negative
|
||||
* direction) and append it onto the current path within @cr. The arc
|
||||
* will be accurate within the current tolerance and given the current
|
||||
* transformation.
|
||||
**/
|
||||
void
|
||||
_cairo_arc_path_negative (cairo_t *cr,
|
||||
double xc,
|
||||
double yc,
|
||||
double radius,
|
||||
double angle1,
|
||||
double angle2)
|
||||
{
|
||||
_cairo_arc_in_direction (cr, xc, yc,
|
||||
radius,
|
||||
angle2, angle1,
|
||||
CAIRO_DIRECTION_REVERSE);
|
||||
}
|
||||
492
uppdev/plugin/cairo/lib/cairo-array.c
Normal file
492
uppdev/plugin/cairo/lib/cairo-array.c
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/**
|
||||
* _cairo_array_init:
|
||||
*
|
||||
* Initialize a new #cairo_array_t object to store objects each of size
|
||||
* @element_size.
|
||||
*
|
||||
* The #cairo_array_t object provides grow-by-doubling storage. It
|
||||
* never interprets the data passed to it, nor does it provide any
|
||||
* sort of callback mechanism for freeing resources held onto by
|
||||
* stored objects.
|
||||
*
|
||||
* When finished using the array, _cairo_array_fini() should be
|
||||
* called to free resources allocated during use of the array.
|
||||
**/
|
||||
void
|
||||
_cairo_array_init (cairo_array_t *array, int element_size)
|
||||
{
|
||||
array->size = 0;
|
||||
array->num_elements = 0;
|
||||
array->element_size = element_size;
|
||||
array->elements = NULL;
|
||||
|
||||
array->is_snapshot = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_init_snapshot:
|
||||
* @array: A #cairo_array_t to be initialized as a snapshot
|
||||
* @other: The #cairo_array_t from which to create the snapshot
|
||||
*
|
||||
* Initialize @array as an immutable copy of @other. It is an error to
|
||||
* call an array-modifying function (other than _cairo_array_fini) on
|
||||
* @array after calling this function.
|
||||
**/
|
||||
void
|
||||
_cairo_array_init_snapshot (cairo_array_t *array,
|
||||
const cairo_array_t *other)
|
||||
{
|
||||
array->size = other->size;
|
||||
array->num_elements = other->num_elements;
|
||||
array->element_size = other->element_size;
|
||||
array->elements = other->elements;
|
||||
|
||||
array->is_snapshot = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_fini:
|
||||
* @array: A #cairo_array_t
|
||||
*
|
||||
* Free all resources associated with @array. After this call, @array
|
||||
* should not be used again without a subsequent call to
|
||||
* _cairo_array_init() again first.
|
||||
**/
|
||||
void
|
||||
_cairo_array_fini (cairo_array_t *array)
|
||||
{
|
||||
if (array->is_snapshot)
|
||||
return;
|
||||
|
||||
if (array->elements) {
|
||||
free (* array->elements);
|
||||
free (array->elements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_grow_by:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Increase the size of @array (if needed) so that there are at least
|
||||
* @additional free spaces in the array. The actual size of the array
|
||||
* is always increased by doubling as many times as necessary.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
|
||||
{
|
||||
char *new_elements;
|
||||
unsigned int old_size = array->size;
|
||||
unsigned int required_size = array->num_elements + additional;
|
||||
unsigned int new_size;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
/* check for integer overflow */
|
||||
if (required_size > INT_MAX || required_size < array->num_elements)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (required_size <= old_size)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (old_size == 0)
|
||||
new_size = 1;
|
||||
else
|
||||
new_size = old_size * 2;
|
||||
|
||||
while (new_size < required_size)
|
||||
new_size = new_size * 2;
|
||||
|
||||
if (array->elements == NULL) {
|
||||
array->elements = malloc (sizeof (char *));
|
||||
if (array->elements == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
*array->elements = NULL;
|
||||
}
|
||||
|
||||
array->size = new_size;
|
||||
new_elements = _cairo_realloc_ab (*array->elements,
|
||||
array->size, array->element_size);
|
||||
|
||||
if (new_elements == NULL) {
|
||||
array->size = old_size;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
*array->elements = new_elements;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_truncate:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Truncate size of the array to @num_elements if less than the
|
||||
* current size. No memory is actually freed. The stored objects
|
||||
* beyond @num_elements are simply "forgotten".
|
||||
**/
|
||||
void
|
||||
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
if (num_elements < array->num_elements)
|
||||
array->num_elements = num_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_index:
|
||||
* @array: a #cairo_array_t
|
||||
* Returns: A pointer to the object stored at @index.
|
||||
*
|
||||
* If the resulting value is assigned to a pointer to an object of the same
|
||||
* element_size as initially passed to _cairo_array_init() then that
|
||||
* pointer may be used for further direct indexing with []. For
|
||||
* example:
|
||||
*
|
||||
* <informalexample><programlisting>
|
||||
* cairo_array_t array;
|
||||
* double *values;
|
||||
*
|
||||
* _cairo_array_init (&array, sizeof(double));
|
||||
* ... calls to _cairo_array_append() here ...
|
||||
*
|
||||
* values = _cairo_array_index (&array, 0);
|
||||
* for (i = 0; i < _cairo_array_num_elements (&array); i++)
|
||||
* ... use values[i] here ...
|
||||
* </programlisting></informalexample>
|
||||
**/
|
||||
void *
|
||||
_cairo_array_index (cairo_array_t *array, unsigned int index)
|
||||
{
|
||||
/* We allow an index of 0 for the no-elements case.
|
||||
* This makes for cleaner calling code which will often look like:
|
||||
*
|
||||
* elements = _cairo_array_index (array, num_elements);
|
||||
* for (i=0; i < num_elements; i++) {
|
||||
* ... use elements[i] here ...
|
||||
* }
|
||||
*
|
||||
* which in the num_elements==0 case gets the NULL pointer here,
|
||||
* but never dereferences it.
|
||||
*/
|
||||
if (index == 0 && array->num_elements == 0)
|
||||
return NULL;
|
||||
|
||||
assert (index < array->num_elements);
|
||||
|
||||
return (void *) &(*array->elements)[index * array->element_size];
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_copy_element:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Copy a single element out of the array from index @index into the
|
||||
* location pointed to by @dst.
|
||||
**/
|
||||
void
|
||||
_cairo_array_copy_element (cairo_array_t *array, int index, void *dst)
|
||||
{
|
||||
memcpy (dst, _cairo_array_index (array, index), array->element_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_append:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Append a single item onto the array by growing the array by at
|
||||
* least one element, then copying element_size bytes from @element
|
||||
* into the array. The address of the resulting object within the
|
||||
* array can be determined with:
|
||||
*
|
||||
* _cairo_array_index (array, _cairo_array_num_elements (array) - 1);
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
|
||||
* operation.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_append (cairo_array_t *array,
|
||||
const void *element)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
return _cairo_array_append_multiple (array, element, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_append:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Append one or more items onto the array by growing the array by
|
||||
* @num_elements, then copying @num_elements * element_size bytes from
|
||||
* @elements into the array.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
|
||||
* operation.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_append_multiple (cairo_array_t *array,
|
||||
const void *elements,
|
||||
int num_elements)
|
||||
{
|
||||
cairo_status_t status;
|
||||
void *dest;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
status = _cairo_array_allocate (array, num_elements, &dest);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
memcpy (dest, elements, num_elements * array->element_size);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_allocate:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Allocate space at the end of the array for @num_elements additional
|
||||
* elements, providing the address of the new memory chunk in
|
||||
* @elements. This memory will be unitialized, but will be accounted
|
||||
* for in the return value of _cairo_array_num_elements().
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
|
||||
* operation.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_allocate (cairo_array_t *array,
|
||||
unsigned int num_elements,
|
||||
void **elements)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
status = _cairo_array_grow_by (array, num_elements);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
assert (array->num_elements + num_elements <= array->size);
|
||||
|
||||
*elements = &(*array->elements)[array->num_elements * array->element_size];
|
||||
|
||||
array->num_elements += num_elements;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_num_elements:
|
||||
* @array: a #cairo_array_t
|
||||
* Returns: The number of elements stored in @array.
|
||||
*
|
||||
* This space was left intentionally blank, but gtk-doc filled it.
|
||||
**/
|
||||
int
|
||||
_cairo_array_num_elements (cairo_array_t *array)
|
||||
{
|
||||
return array->num_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_size:
|
||||
* @array: a #cairo_array_t
|
||||
* Returns: The number of elements for which there is currently space
|
||||
* allocated in @array.
|
||||
*
|
||||
* This space was left intentionally blank, but gtk-doc filled it.
|
||||
**/
|
||||
int
|
||||
_cairo_array_size (cairo_array_t *array)
|
||||
{
|
||||
return array->size;
|
||||
}
|
||||
|
||||
/* #cairo_user_data_array_t */
|
||||
|
||||
typedef struct {
|
||||
const cairo_user_data_key_t *key;
|
||||
void *user_data;
|
||||
cairo_destroy_func_t destroy;
|
||||
} cairo_user_data_slot_t;
|
||||
|
||||
/**
|
||||
* _cairo_user_data_array_init:
|
||||
* @array: a #cairo_user_data_array_t
|
||||
*
|
||||
* Initializes a #cairo_user_data_array_t structure for future
|
||||
* use. After initialization, the array has no keys. Call
|
||||
* _cairo_user_data_array_fini() to free any allocated memory
|
||||
* when done using the array.
|
||||
**/
|
||||
void
|
||||
_cairo_user_data_array_init (cairo_user_data_array_t *array)
|
||||
{
|
||||
_cairo_array_init (array, sizeof (cairo_user_data_slot_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_user_data_array_fini:
|
||||
* @array: a #cairo_user_data_array_t
|
||||
*
|
||||
* Destroys all current keys in the user data array and deallocates
|
||||
* any memory allocated for the array itself.
|
||||
**/
|
||||
void
|
||||
_cairo_user_data_array_fini (cairo_user_data_array_t *array)
|
||||
{
|
||||
int i, num_slots;
|
||||
cairo_user_data_slot_t *slots;
|
||||
|
||||
num_slots = array->num_elements;
|
||||
slots = _cairo_array_index (array, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].user_data != NULL && slots[i].destroy != NULL)
|
||||
slots[i].destroy (slots[i].user_data);
|
||||
}
|
||||
|
||||
_cairo_array_fini (array);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_user_data_array_get_data:
|
||||
* @array: a #cairo_user_data_array_t
|
||||
* @key: the address of the #cairo_user_data_key_t the user data was
|
||||
* attached to
|
||||
*
|
||||
* Returns user data previously attached using the specified
|
||||
* key. If no user data has been attached with the given key this
|
||||
* function returns %NULL.
|
||||
*
|
||||
* Return value: the user data previously attached or %NULL.
|
||||
**/
|
||||
void *
|
||||
_cairo_user_data_array_get_data (cairo_user_data_array_t *array,
|
||||
const cairo_user_data_key_t *key)
|
||||
{
|
||||
int i, num_slots;
|
||||
cairo_user_data_slot_t *slots;
|
||||
|
||||
/* We allow this to support degenerate objects such as cairo_surface_nil. */
|
||||
if (array == NULL)
|
||||
return NULL;
|
||||
|
||||
num_slots = array->num_elements;
|
||||
slots = _cairo_array_index (array, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].key == key)
|
||||
return slots[i].user_data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_user_data_array_set_data:
|
||||
* @array: a #cairo_user_data_array_t
|
||||
* @key: the address of a #cairo_user_data_key_t to attach the user data to
|
||||
* @user_data: the user data to attach
|
||||
* @destroy: a #cairo_destroy_func_t which will be called when the
|
||||
* user data array is destroyed or when new user data is attached using the
|
||||
* same key.
|
||||
*
|
||||
* Attaches user data to a user data array. To remove user data,
|
||||
* call this function with the key that was used to set it and %NULL
|
||||
* for @data.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
|
||||
* slot could not be allocated for the user data.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_user_data_array_set_data (cairo_user_data_array_t *array,
|
||||
const cairo_user_data_key_t *key,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int i, num_slots;
|
||||
cairo_user_data_slot_t *slots, *slot, new_slot;
|
||||
|
||||
if (user_data) {
|
||||
new_slot.key = key;
|
||||
new_slot.user_data = user_data;
|
||||
new_slot.destroy = destroy;
|
||||
} else {
|
||||
new_slot.key = NULL;
|
||||
new_slot.user_data = NULL;
|
||||
new_slot.destroy = NULL;
|
||||
}
|
||||
|
||||
slot = NULL;
|
||||
num_slots = array->num_elements;
|
||||
slots = _cairo_array_index (array, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].key == key) {
|
||||
slot = &slots[i];
|
||||
if (slot->destroy && slot->user_data)
|
||||
slot->destroy (slot->user_data);
|
||||
break;
|
||||
}
|
||||
if (user_data && slots[i].user_data == NULL) {
|
||||
slot = &slots[i]; /* Have to keep searching for an exact match */
|
||||
}
|
||||
}
|
||||
|
||||
if (slot) {
|
||||
*slot = new_slot;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = _cairo_array_append (array, &new_slot);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
104
uppdev/plugin/cairo/lib/cairo-atomic-private.h
Normal file
104
uppdev/plugin/cairo/lib/cairo-atomic-private.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_ATOMIC_PRIVATE_H
|
||||
#define CAIRO_ATOMIC_PRIVATE_H
|
||||
|
||||
# include "cairo-compiler-private.h"
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if HAVE_INTEL_ATOMIC_PRIMITIVES
|
||||
|
||||
#define HAS_ATOMIC_OPS 1
|
||||
|
||||
typedef int cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAS_ATOMIC_OPS
|
||||
|
||||
typedef int cairo_atomic_int_t;
|
||||
|
||||
cairo_private void
|
||||
_cairo_atomic_int_inc (int *x);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_atomic_int_dec_and_test (int *x);
|
||||
|
||||
cairo_private int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
|
||||
# include "cairo-compiler-private.h"
|
||||
|
||||
cairo_private int
|
||||
_cairo_atomic_int_get (int *x);
|
||||
|
||||
cairo_private void
|
||||
_cairo_atomic_int_set (int *x, int value);
|
||||
|
||||
#else
|
||||
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_int_set(x, value) ((*x) = value)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define _cairo_status_set_error(status, err) do { \
|
||||
/* hide compiler warnings about cairo_status_t != int (gcc treats its as \
|
||||
* an unsigned integer instead, and about ignoring the return value. */ \
|
||||
int ret__ = _cairo_atomic_int_cmpxchg ((int *) status, CAIRO_STATUS_SUCCESS, err); \
|
||||
(void) ret__; \
|
||||
} while (0)
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
96
uppdev/plugin/cairo/lib/cairo-atomic.c
Normal file
96
uppdev/plugin/cairo/lib/cairo-atomic.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-atomic-private.h"
|
||||
#include "cairo-mutex-private.h"
|
||||
|
||||
#ifndef HAS_ATOMIC_OPS
|
||||
void
|
||||
_cairo_atomic_int_inc (int *x)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x += 1;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_atomic_int_dec_and_test (int *x)
|
||||
{
|
||||
cairo_bool_t ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = --*x == 0;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
if (ret == oldv)
|
||||
*x = newv;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
int
|
||||
_cairo_atomic_int_get (int *x)
|
||||
{
|
||||
int ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_atomic_int_set (int *x, int value)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x = value;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
}
|
||||
#endif
|
||||
132
uppdev/plugin/cairo/lib/cairo-base85-stream.c
Normal file
132
uppdev/plugin/cairo/lib/cairo-base85-stream.c
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Author(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef struct _cairo_base85_stream {
|
||||
cairo_output_stream_t base;
|
||||
cairo_output_stream_t *output;
|
||||
unsigned char four_tuple[4];
|
||||
int pending;
|
||||
} cairo_base85_stream_t;
|
||||
|
||||
static void
|
||||
_expand_four_tuple_to_five (unsigned char four_tuple[4],
|
||||
unsigned char five_tuple[5],
|
||||
cairo_bool_t *all_zero)
|
||||
{
|
||||
uint32_t value;
|
||||
int digit, i;
|
||||
|
||||
value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
|
||||
if (all_zero)
|
||||
*all_zero = TRUE;
|
||||
for (i = 0; i < 5; i++) {
|
||||
digit = value % 85;
|
||||
if (digit != 0 && all_zero)
|
||||
*all_zero = FALSE;
|
||||
five_tuple[4-i] = digit + 33;
|
||||
value = value / 85;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base85_stream_write (cairo_output_stream_t *base,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base;
|
||||
const unsigned char *ptr = data;
|
||||
unsigned char five_tuple[5];
|
||||
cairo_bool_t is_zero;
|
||||
|
||||
while (length) {
|
||||
stream->four_tuple[stream->pending++] = *ptr++;
|
||||
length--;
|
||||
if (stream->pending == 4) {
|
||||
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, &is_zero);
|
||||
if (is_zero)
|
||||
_cairo_output_stream_write (stream->output, "z", 1);
|
||||
else
|
||||
_cairo_output_stream_write (stream->output, five_tuple, 5);
|
||||
stream->pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base85_stream_close (cairo_output_stream_t *base)
|
||||
{
|
||||
cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base;
|
||||
unsigned char five_tuple[5];
|
||||
|
||||
if (stream->pending) {
|
||||
memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending);
|
||||
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL);
|
||||
_cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1);
|
||||
}
|
||||
|
||||
/* Mark end of base85 data */
|
||||
_cairo_output_stream_printf (stream->output, "~>");
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
cairo_base85_stream_t *stream;
|
||||
|
||||
if (output->status)
|
||||
return _cairo_output_stream_create_in_error (output->status);
|
||||
|
||||
stream = malloc (sizeof (cairo_base85_stream_t));
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base,
|
||||
_cairo_base85_stream_write,
|
||||
_cairo_base85_stream_close);
|
||||
stream->output = output;
|
||||
stream->pending = 0;
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
1935
uppdev/plugin/cairo/lib/cairo-bentley-ottmann.c
Normal file
1935
uppdev/plugin/cairo/lib/cairo-bentley-ottmann.c
Normal file
File diff suppressed because it is too large
Load diff
60
uppdev/plugin/cairo/lib/cairo-beos.h
Normal file
60
uppdev/plugin/cairo/lib/cairo-beos.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Christian Biesinger <cbiesinger@web.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Christian Biesinger
|
||||
* <cbiesinger@web.de>
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_BEOS_H
|
||||
#define CAIRO_BEOS_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_BEOS_SURFACE
|
||||
|
||||
#include <View.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_beos_surface_create (BView* view);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_beos_surface_create_for_bitmap (BView* view,
|
||||
BBitmap* bmp);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_BEOS_SURFACE */
|
||||
# error Cairo was not compiled with support for the beos backend
|
||||
#endif /* CAIRO_HAS_BEOS_SURFACE */
|
||||
|
||||
#endif /* CAIRO_BEOS_H */
|
||||
126
uppdev/plugin/cairo/lib/cairo-cache-private.h
Normal file
126
uppdev/plugin/cairo/lib/cairo-cache-private.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc.
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_CACHE_PRIVATE_H
|
||||
#define CAIRO_CACHE_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
/**
|
||||
* cairo_cache_entry_t:
|
||||
*
|
||||
* A #cairo_cache_entry_t contains both a key and a value for
|
||||
* #cairo_cache_t. User-derived types for #cairo_cache_entry_t must
|
||||
* have a #cairo_cache_entry_t as their first field. For example:
|
||||
*
|
||||
* typedef _my_entry {
|
||||
* cairo_cache_entry_t base;
|
||||
* ... Remainder of key and value fields here ..
|
||||
* } my_entry_t;
|
||||
*
|
||||
* which then allows a pointer to my_entry_t to be passed to any of
|
||||
* the #cairo_cache_t functions as follows without requiring a cast:
|
||||
*
|
||||
* _cairo_cache_insert (cache, &my_entry->base, size);
|
||||
*
|
||||
* IMPORTANT: The caller is responsible for initializing
|
||||
* my_entry->base.hash with a hash code derived from the key. The
|
||||
* essential property of the hash code is that keys_equal must never
|
||||
* return %TRUE for two keys that have different hashes. The best hash
|
||||
* code will reduce the frequency of two keys with the same code for
|
||||
* which keys_equal returns %FALSE.
|
||||
*
|
||||
* The user must also initialize my_entry->base.size to indicate
|
||||
* the size of the current entry. What units to use for size is
|
||||
* entirely up to the caller, (though the same units must be used for
|
||||
* the max_size parameter passed to _cairo_cache_create()). If all
|
||||
* entries are close to the same size, the simplest thing to do is to
|
||||
* just use units of "entries", (eg. set size==1 in all entries and
|
||||
* set max_size to the number of entries which you want to be saved
|
||||
* in the cache).
|
||||
*
|
||||
* Which parts of the entry make up the "key" and which part make up
|
||||
* the value are entirely up to the caller, (as determined by the
|
||||
* computation going into base.hash as well as the keys_equal
|
||||
* function). A few of the #cairo_cache_t functions accept an entry which
|
||||
* will be used exclusively as a "key", (indicated by a parameter name
|
||||
* of key). In these cases, the value-related fields of the entry need
|
||||
* not be initialized if so desired.
|
||||
**/
|
||||
typedef struct _cairo_cache_entry {
|
||||
unsigned long hash;
|
||||
unsigned long size;
|
||||
} cairo_cache_entry_t;
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_cache_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
typedef void
|
||||
(*cairo_cache_callback_func_t) (void *entry,
|
||||
void *closure);
|
||||
|
||||
cairo_private cairo_cache_t *
|
||||
_cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_destroy (cairo_cache_t *cache);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_freeze (cairo_cache_t *cache);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_thaw (cairo_cache_t *cache);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_cache_lookup (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *key,
|
||||
cairo_cache_entry_t **entry_return);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_cache_insert (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_foreach (cairo_cache_t *cache,
|
||||
cairo_cache_callback_func_t cache_callback,
|
||||
void *closure);
|
||||
|
||||
#endif
|
||||
363
uppdev/plugin/cairo/lib/cairo-cache.c
Normal file
363
uppdev/plugin/cairo/lib/cairo-cache.c
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc.
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static void
|
||||
_cairo_cache_remove (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry);
|
||||
|
||||
static void
|
||||
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
|
||||
unsigned long additional);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_cache_init (cairo_cache_t *cache,
|
||||
cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size)
|
||||
{
|
||||
cache->hash_table = _cairo_hash_table_create (keys_equal);
|
||||
if (cache->hash_table == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
cache->entry_destroy = entry_destroy;
|
||||
|
||||
cache->max_size = max_size;
|
||||
cache->size = 0;
|
||||
|
||||
cache->freeze_count = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_cache_fini (cairo_cache_t *cache)
|
||||
{
|
||||
cairo_cache_entry_t *entry;
|
||||
|
||||
/* We have to manually remove all entries from the cache ourselves
|
||||
* rather than relying on _cairo_hash_table_destroy() to do that
|
||||
* since otherwise the cache->entry_destroy callback would not get
|
||||
* called on each entry. */
|
||||
|
||||
while (1) {
|
||||
entry = _cairo_hash_table_random_entry (cache->hash_table, NULL);
|
||||
if (entry == NULL)
|
||||
break;
|
||||
_cairo_cache_remove (cache, entry);
|
||||
}
|
||||
|
||||
_cairo_hash_table_destroy (cache->hash_table);
|
||||
cache->size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_create:
|
||||
* @keys_equal: a function to return %TRUE if two keys are equal
|
||||
* @entry_destroy: destroy notifier for cache entries
|
||||
* @max_size: the maximum size for this cache
|
||||
* Returns: the newly created #cairo_cache_t
|
||||
*
|
||||
* Creates a new cache using the keys_equal() function to determine
|
||||
* the equality of entries.
|
||||
*
|
||||
* Data is provided to the cache in the form of user-derived version
|
||||
* of #cairo_cache_entry_t. A cache entry must be able to hold hash
|
||||
* code, a size, and the key/value pair being stored in the
|
||||
* cache. Sometimes only the key will be necessary, (as in
|
||||
* _cairo_cache_lookup()), and in these cases the value portion of the
|
||||
* entry need not be initialized.
|
||||
*
|
||||
* The units for max_size can be chosen by the caller, but should be
|
||||
* consistent with the units of the size field of cache entries. When
|
||||
* adding an entry with _cairo_cache_insert() if the total size of
|
||||
* entries in the cache would exceed max_size then entries will be
|
||||
* removed at random until the new entry would fit or the cache is
|
||||
* empty. Then the new entry is inserted.
|
||||
*
|
||||
* There are cases in which the automatic removal of entries is
|
||||
* undesired. If the cache entries have reference counts, then it is a
|
||||
* simple matter to use the reference counts to ensure that entries
|
||||
* continue to live even after being ejected from the cache. However,
|
||||
* in some cases the memory overhead of adding a reference count to
|
||||
* the entry would be objectionable. In such cases, the
|
||||
* _cairo_cache_freeze() and _cairo_cache_thaw() calls can be
|
||||
* used to establish a window during which no automatic removal of
|
||||
* entries will occur.
|
||||
**/
|
||||
cairo_cache_t *
|
||||
_cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_cache_t *cache;
|
||||
|
||||
cache = malloc (sizeof (cairo_cache_t));
|
||||
if (cache == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = _cairo_cache_init (cache, keys_equal, entry_destroy, max_size);
|
||||
if (status) {
|
||||
free (cache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_destroy:
|
||||
* @cache: a cache to destroy
|
||||
*
|
||||
* Immediately destroys the given cache, freeing all resources
|
||||
* associated with it. As part of this process, the entry_destroy()
|
||||
* function, (as passed to _cairo_cache_create()), will be called for
|
||||
* each entry in the cache.
|
||||
**/
|
||||
void
|
||||
_cairo_cache_destroy (cairo_cache_t *cache)
|
||||
{
|
||||
_cairo_cache_fini (cache);
|
||||
|
||||
free (cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_freeze:
|
||||
* @cache: a cache with some precious entries in it (or about to be
|
||||
* added)
|
||||
*
|
||||
* Disable the automatic ejection of entries from the cache. For as
|
||||
* long as the cache is "frozen", calls to _cairo_cache_insert() will
|
||||
* add new entries to the cache regardless of how large the cache
|
||||
* grows. See _cairo_cache_thaw().
|
||||
*
|
||||
* Note: Multiple calls to _cairo_cache_freeze() will stack, in that
|
||||
* the cache will remain "frozen" until a corresponding number of
|
||||
* calls are made to _cairo_cache_thaw().
|
||||
**/
|
||||
void
|
||||
_cairo_cache_freeze (cairo_cache_t *cache)
|
||||
{
|
||||
assert (cache->freeze_count >= 0);
|
||||
|
||||
cache->freeze_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_thaw:
|
||||
* @cache: a cache, just after the entries in it have become less
|
||||
* precious
|
||||
*
|
||||
* Cancels the effects of _cairo_cache_freeze().
|
||||
*
|
||||
* When a number of calls to _cairo_cache_thaw() is made corresponding
|
||||
* to the number of calls to _cairo_cache_freeze() the cache will no
|
||||
* longer be "frozen". If the cache had grown larger than max_size
|
||||
* while frozen, entries will immediately be ejected (by random) from
|
||||
* the cache until the cache is smaller than max_size. Also, the
|
||||
* automatic ejection of entries on _cairo_cache_insert() will resume.
|
||||
**/
|
||||
void
|
||||
_cairo_cache_thaw (cairo_cache_t *cache)
|
||||
{
|
||||
assert (cache->freeze_count > 0);
|
||||
|
||||
cache->freeze_count--;
|
||||
|
||||
if (cache->freeze_count == 0)
|
||||
_cairo_cache_shrink_to_accommodate (cache, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_lookup:
|
||||
* @cache: a cache
|
||||
* @key: the key of interest
|
||||
* @entry_return: pointer for return value
|
||||
*
|
||||
* Performs a lookup in @cache looking for an entry which has a key
|
||||
* that matches @key, (as determined by the keys_equal() function
|
||||
* passed to _cairo_cache_create()).
|
||||
*
|
||||
* Return value: %TRUE if there is an entry in the cache that matches
|
||||
* @key, (which will now be in *entry_return). %FALSE otherwise, (in
|
||||
* which case *entry_return will be %NULL).
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_cache_lookup (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *key,
|
||||
cairo_cache_entry_t **entry_return)
|
||||
{
|
||||
return _cairo_hash_table_lookup (cache->hash_table,
|
||||
(cairo_hash_entry_t *) key,
|
||||
(cairo_hash_entry_t **) entry_return);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_remove_random:
|
||||
* @cache: a cache
|
||||
*
|
||||
* Remove a random entry from the cache.
|
||||
*
|
||||
* Return value: %TRUE if an entry was successfully removed.
|
||||
* %FALSE if there are no entries that can be removed.
|
||||
**/
|
||||
static cairo_bool_t
|
||||
_cairo_cache_remove_random (cairo_cache_t *cache)
|
||||
{
|
||||
cairo_cache_entry_t *entry;
|
||||
|
||||
entry = _cairo_hash_table_random_entry (cache->hash_table, NULL);
|
||||
if (entry == NULL)
|
||||
return FALSE;
|
||||
|
||||
_cairo_cache_remove (cache, entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_shrink_to_accommodate:
|
||||
* @cache: a cache
|
||||
* @additional: additional size requested in bytes
|
||||
*
|
||||
* If cache is not frozen, eject entries randomly until the size of
|
||||
* the cache is at least @additional bytes less than
|
||||
* cache->max_size. That is, make enough room to accommodate a new
|
||||
* entry of size @additional.
|
||||
**/
|
||||
static void
|
||||
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
|
||||
unsigned long additional)
|
||||
{
|
||||
if (cache->freeze_count)
|
||||
return;
|
||||
|
||||
while (cache->size + additional > cache->max_size) {
|
||||
if (! _cairo_cache_remove_random (cache))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_insert:
|
||||
* @cache: a cache
|
||||
* @entry: an entry to be inserted
|
||||
*
|
||||
* Insert @entry into the cache. If an entry exists in the cache with
|
||||
* a matching key, then the old entry will be removed first, (and the
|
||||
* entry_destroy() callback will be called on it).
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_cache_insert (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_cache_shrink_to_accommodate (cache, entry->size);
|
||||
|
||||
status = _cairo_hash_table_insert (cache->hash_table,
|
||||
(cairo_hash_entry_t *) entry);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cache->size += entry->size;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_remove:
|
||||
* @cache: a cache
|
||||
* @entry: an entry that exists in the cache
|
||||
*
|
||||
* Remove an existing entry from the cache.
|
||||
*
|
||||
* (Note: If any caller wanted access to a non-static version of this
|
||||
* function, an improved version would require only a key rather than
|
||||
* an entry. Fixing that would require fixing _cairo_hash_table_remove
|
||||
* to return (a copy of?) the entry being removed.)
|
||||
**/
|
||||
static void
|
||||
_cairo_cache_remove (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry)
|
||||
{
|
||||
cache->size -= entry->size;
|
||||
|
||||
_cairo_hash_table_remove (cache->hash_table,
|
||||
(cairo_hash_entry_t *) entry);
|
||||
|
||||
if (cache->entry_destroy)
|
||||
cache->entry_destroy (entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_foreach:
|
||||
* @cache: a cache
|
||||
* @cache_callback: function to be called for each entry
|
||||
* @closure: additional argument to be passed to @cache_callback
|
||||
*
|
||||
* Call @cache_callback for each entry in the cache, in a
|
||||
* non-specified order.
|
||||
**/
|
||||
void
|
||||
_cairo_cache_foreach (cairo_cache_t *cache,
|
||||
cairo_cache_callback_func_t cache_callback,
|
||||
void *closure)
|
||||
{
|
||||
_cairo_hash_table_foreach (cache->hash_table,
|
||||
cache_callback,
|
||||
closure);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
_cairo_hash_string (const char *c)
|
||||
{
|
||||
/* This is the djb2 hash. */
|
||||
unsigned long hash = 5381;
|
||||
while (c && *c)
|
||||
hash = ((hash << 5) + hash) + *c++;
|
||||
return hash;
|
||||
}
|
||||
2289
uppdev/plugin/cairo/lib/cairo-cff-subset.c
Normal file
2289
uppdev/plugin/cairo/lib/cairo-cff-subset.c
Normal file
File diff suppressed because it is too large
Load diff
136
uppdev/plugin/cairo/lib/cairo-clip-private.h
Normal file
136
uppdev/plugin/cairo/lib/cairo-clip-private.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_CLIP_PRIVATE_H
|
||||
#define CAIRO_CLIP_PRIVATE_H
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
|
||||
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
|
||||
|
||||
struct _cairo_clip_path {
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
cairo_clip_path_t *prev;
|
||||
};
|
||||
|
||||
struct _cairo_clip {
|
||||
cairo_clip_mode_t mode;
|
||||
|
||||
cairo_bool_t all_clipped;
|
||||
|
||||
/*
|
||||
* Mask-based clipping for cases where the backend
|
||||
* clipping isn't sufficiently able.
|
||||
*
|
||||
* The rectangle here represents the
|
||||
* portion of the destination surface that this
|
||||
* clip surface maps to, it does not
|
||||
* represent the extents of the clip region or
|
||||
* clip paths
|
||||
*/
|
||||
cairo_surface_t *surface;
|
||||
cairo_rectangle_int_t surface_rect;
|
||||
/*
|
||||
* Surface clip serial number to store
|
||||
* in the surface when this clip is set
|
||||
*/
|
||||
unsigned int serial;
|
||||
/*
|
||||
* A clip region that can be placed in the surface
|
||||
*/
|
||||
cairo_region_t region;
|
||||
cairo_bool_t has_region;
|
||||
/*
|
||||
* If the surface supports path clipping, we store the list of
|
||||
* clipping paths that has been set here as a linked list.
|
||||
*/
|
||||
cairo_clip_path_t *path;
|
||||
};
|
||||
|
||||
cairo_private void
|
||||
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
||||
cairo_clip_t *other,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private void
|
||||
_cairo_clip_reset (cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_clip (cairo_clip_t *clip,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
cairo_region_t *region);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents);
|
||||
|
||||
cairo_private void
|
||||
_cairo_clip_translate (cairo_clip_t *clip,
|
||||
cairo_fixed_t tx,
|
||||
cairo_fixed_t ty);
|
||||
|
||||
cairo_private cairo_rectangle_list_t*
|
||||
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
|
||||
|
||||
#endif /* CAIRO_CLIP_PRIVATE_H */
|
||||
858
uppdev/plugin/cairo/lib/cairo-clip.c
Normal file
858
uppdev/plugin/cairo/lib/cairo-clip.c
Normal file
|
|
@ -0,0 +1,858 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
static cairo_clip_path_t *
|
||||
_cairo_clip_path_reference (cairo_clip_path_t *clip_path);
|
||||
|
||||
static void
|
||||
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
|
||||
|
||||
void
|
||||
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
|
||||
{
|
||||
if (target)
|
||||
clip->mode = _cairo_surface_get_clip_mode (target);
|
||||
else
|
||||
clip->mode = CAIRO_CLIP_MODE_MASK;
|
||||
|
||||
clip->all_clipped = FALSE;
|
||||
|
||||
clip->surface = NULL;
|
||||
clip->surface_rect.x = 0;
|
||||
clip->surface_rect.y = 0;
|
||||
clip->surface_rect.width = 0;
|
||||
clip->surface_rect.height = 0;
|
||||
|
||||
clip->serial = 0;
|
||||
|
||||
_cairo_region_init (&clip->region);
|
||||
clip->has_region = FALSE;
|
||||
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
{
|
||||
clip->mode = other->mode;
|
||||
|
||||
clip->all_clipped = other->all_clipped;
|
||||
|
||||
clip->surface = cairo_surface_reference (other->surface);
|
||||
clip->surface_rect = other->surface_rect;
|
||||
|
||||
clip->serial = other->serial;
|
||||
|
||||
_cairo_region_init (&clip->region);
|
||||
|
||||
if (other->has_region) {
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_region_copy (&clip->region, &other->region);
|
||||
if (status) {
|
||||
_cairo_region_fini (&clip->region);
|
||||
cairo_surface_destroy (clip->surface);
|
||||
return status;
|
||||
}
|
||||
clip->has_region = TRUE;
|
||||
} else {
|
||||
clip->has_region = FALSE;
|
||||
}
|
||||
|
||||
clip->path = _cairo_clip_path_reference (other->path);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_clip_reset (cairo_clip_t *clip)
|
||||
{
|
||||
clip->all_clipped = FALSE;
|
||||
|
||||
/* destroy any existing clip-region artifacts */
|
||||
cairo_surface_destroy (clip->surface);
|
||||
clip->surface = NULL;
|
||||
|
||||
clip->serial = 0;
|
||||
|
||||
if (clip->has_region) {
|
||||
/* _cairo_region_fini just releases the resources used but
|
||||
* doesn't bother with leaving the region in a valid state.
|
||||
* So _cairo_region_init has to be called afterwards. */
|
||||
_cairo_region_fini (&clip->region);
|
||||
_cairo_region_init (&clip->region);
|
||||
|
||||
clip->has_region = FALSE;
|
||||
}
|
||||
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_clip_set_all_clipped (cairo_clip_t *clip, cairo_surface_t *target)
|
||||
{
|
||||
_cairo_clip_reset (clip);
|
||||
|
||||
clip->all_clipped = TRUE;
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
}
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
while (clip_path) {
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_box_t extents;
|
||||
cairo_rectangle_int_t extents_rect;
|
||||
|
||||
_cairo_box_from_rectangle (&extents, rectangle);
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
_cairo_traps_limit (&traps, &extents);
|
||||
|
||||
status = _cairo_path_fixed_fill_to_traps (&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
&traps);
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_traps_extents (&traps, &extents);
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
_cairo_box_round_to_rectangle (&extents, &extents_rect);
|
||||
if (! _cairo_rectangle_intersect (rectangle, &extents_rect))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
clip_path = clip_path->prev;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->all_clipped) {
|
||||
*rectangle = clip->surface_rect;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (clip->path) {
|
||||
status = _cairo_clip_path_intersect_to_rectangle (clip->path,
|
||||
rectangle);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
cairo_region_t intersection;
|
||||
|
||||
_cairo_region_init_rect (&intersection, rectangle);
|
||||
|
||||
status = _cairo_region_intersect (&intersection, &clip->region,
|
||||
&intersection);
|
||||
|
||||
if (!status)
|
||||
_cairo_region_get_extents (&intersection, rectangle);
|
||||
|
||||
_cairo_region_fini (&intersection);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->surface)
|
||||
is_empty = _cairo_rectangle_intersect (rectangle, &clip->surface_rect);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->all_clipped) {
|
||||
cairo_region_t clip_rect;
|
||||
|
||||
_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
|
||||
|
||||
status = _cairo_region_intersect (region, &clip_rect, region);
|
||||
|
||||
_cairo_region_fini (&clip_rect);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->path) {
|
||||
/* Intersect clip path into region. */
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
status = _cairo_region_intersect (region, &clip->region, region);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->surface) {
|
||||
cairo_region_t clip_rect;
|
||||
|
||||
_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
|
||||
|
||||
status = _cairo_region_intersect (region, &clip_rect, region);
|
||||
|
||||
_cairo_region_fini (&clip_rect);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Combines the region of clip->surface given by extents in
|
||||
* device backend coordinates into the given temporary surface,
|
||||
* which has its origin at dst_x, dst_y in backend coordinates
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
{
|
||||
cairo_surface_pattern_t pattern;
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern, clip->surface);
|
||||
|
||||
status = _cairo_surface_composite (op,
|
||||
&pattern.base,
|
||||
NULL,
|
||||
dst,
|
||||
extents->x - clip->surface_rect.x,
|
||||
extents->y - clip->surface_rect.y,
|
||||
0, 0,
|
||||
extents->x - dst_x,
|
||||
extents->y - dst_y,
|
||||
extents->width, extents->height);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_intersect_path (cairo_clip_t *clip,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_clip_path_t *clip_path;
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip->mode != CAIRO_CLIP_MODE_PATH)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
clip_path = malloc (sizeof (cairo_clip_path_t));
|
||||
if (clip_path == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
|
||||
if (status) {
|
||||
free (clip_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);
|
||||
clip_path->fill_rule = fill_rule;
|
||||
clip_path->tolerance = tolerance;
|
||||
clip_path->antialias = antialias;
|
||||
clip_path->prev = clip->path;
|
||||
clip->path = clip_path;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_clip_path_t *
|
||||
_cairo_clip_path_reference (cairo_clip_path_t *clip_path)
|
||||
{
|
||||
if (clip_path == NULL)
|
||||
return NULL;
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
|
||||
|
||||
_cairo_reference_count_inc (&clip_path->ref_count);
|
||||
|
||||
return clip_path;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
|
||||
{
|
||||
if (clip_path == NULL)
|
||||
return;
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&clip_path->ref_count))
|
||||
return;
|
||||
|
||||
_cairo_path_fixed_fini (&clip_path->path);
|
||||
_cairo_clip_path_destroy (clip_path->prev);
|
||||
free (clip_path);
|
||||
}
|
||||
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_clip_intersect_region (cairo_clip_t *clip,
|
||||
cairo_traps_t *traps,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_region_t region;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->mode != CAIRO_CLIP_MODE_REGION)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = _cairo_traps_extract_region (traps, ®ion);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (!clip->has_region) {
|
||||
status = _cairo_region_copy (&clip->region, ®ion);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
clip->has_region = TRUE;
|
||||
} else {
|
||||
cairo_region_t intersection;
|
||||
|
||||
_cairo_region_init (&intersection);
|
||||
|
||||
status = _cairo_region_intersect (&intersection,
|
||||
&clip->region,
|
||||
®ion);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_region_copy (&clip->region, &intersection);
|
||||
|
||||
_cairo_region_fini (&intersection);
|
||||
}
|
||||
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
_cairo_region_fini (®ion);
|
||||
|
||||
if (! _cairo_region_not_empty (&clip->region))
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_intersect_mask (cairo_clip_t *clip,
|
||||
cairo_traps_t *traps,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_box_t extents;
|
||||
cairo_rectangle_int_t surface_rect, target_rect;
|
||||
cairo_surface_t *surface = NULL;
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* Represent the clip as a mask surface. We create a new surface
|
||||
* the size of the intersection of the old mask surface and the
|
||||
* extents of the new clip path. */
|
||||
|
||||
_cairo_traps_extents (traps, &extents);
|
||||
_cairo_box_round_to_rectangle (&extents, &surface_rect);
|
||||
|
||||
if (clip->surface != NULL) {
|
||||
if (! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
/* Intersect with the target surface rectangle so we don't use
|
||||
* more memory and time than we need to. */
|
||||
status = _cairo_surface_get_extents (target, &target_rect);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
if (! _cairo_rectangle_intersect (&surface_rect, &target_rect))
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
if (surface_rect.width == 0 || surface_rect.height == 0)
|
||||
goto DONE;
|
||||
|
||||
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
/* The clipping operation should ideally be something like the following to
|
||||
* avoid having to do as many passes over the data
|
||||
|
||||
if (clip->surface != NULL) {
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
|
||||
} else {
|
||||
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
}
|
||||
status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
surface,
|
||||
antialias,
|
||||
0, 0,
|
||||
0, 0,
|
||||
surface_rect.width,
|
||||
surface_rect.height,
|
||||
traps->traps,
|
||||
traps->num_traps);
|
||||
|
||||
However this operation is not accelerated by pixman
|
||||
|
||||
I believe the best possible operation would probably an unbounded SRC
|
||||
operator. Using SRC we could potentially avoid having to initialize
|
||||
the surface which would be ideal from an efficiency point of view.
|
||||
However, _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_SOURCE) is
|
||||
bounded by the mask.
|
||||
|
||||
*/
|
||||
|
||||
surface = _cairo_surface_create_similar_solid (target,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
surface_rect.width,
|
||||
surface_rect.height,
|
||||
CAIRO_COLOR_TRANSPARENT);
|
||||
if (surface->status) {
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
return surface->status;
|
||||
}
|
||||
|
||||
/* Render the new clipping path into the new mask surface. */
|
||||
|
||||
_cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
|
||||
|
||||
status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
|
||||
&pattern.base,
|
||||
surface,
|
||||
antialias,
|
||||
0, 0,
|
||||
0, 0,
|
||||
surface_rect.width,
|
||||
surface_rect.height,
|
||||
traps->traps,
|
||||
traps->num_traps);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
if (status) {
|
||||
cairo_surface_destroy (surface);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* If there was a clip surface already, combine it with the new
|
||||
* mask surface using the IN operator, so we get the intersection
|
||||
* of the old and new clipping paths. */
|
||||
|
||||
if (clip->surface != NULL) {
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
|
||||
|
||||
status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
NULL,
|
||||
surface,
|
||||
surface_rect.x - clip->surface_rect.x,
|
||||
surface_rect.y - clip->surface_rect.y,
|
||||
0, 0,
|
||||
0, 0,
|
||||
surface_rect.width,
|
||||
surface_rect.height);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
if (status) {
|
||||
cairo_surface_destroy (surface);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
cairo_surface_destroy (clip->surface);
|
||||
clip->surface = surface;
|
||||
clip->surface_rect = surface_rect;
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
|
||||
if (surface_rect.width == 0 || surface_rect.height == 0)
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_clip (cairo_clip_t *clip,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int_t rectangle;
|
||||
cairo_traps_t traps;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* catch the empty clip path */
|
||||
if (! path->has_current_point) {
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = _cairo_clip_intersect_path (clip,
|
||||
path, fill_rule, tolerance,
|
||||
antialias);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
/* Limit the traps to the target surface
|
||||
* - so we don't add more traps than needed. */
|
||||
status = _cairo_surface_get_extents (target, &rectangle);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
cairo_box_t box;
|
||||
|
||||
_cairo_box_from_rectangle (&box, &rectangle);
|
||||
_cairo_traps_limit (&traps, &box);
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_fill_to_traps (path,
|
||||
fill_rule,
|
||||
tolerance,
|
||||
&traps);
|
||||
if (status)
|
||||
goto bail;
|
||||
|
||||
status = _cairo_clip_intersect_region (clip, &traps, target);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto bail;
|
||||
|
||||
status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);
|
||||
|
||||
bail:
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_clip_translate (cairo_clip_t *clip,
|
||||
cairo_fixed_t tx,
|
||||
cairo_fixed_t ty)
|
||||
{
|
||||
if (clip->all_clipped)
|
||||
return;
|
||||
|
||||
if (clip->has_region) {
|
||||
_cairo_region_translate (&clip->region,
|
||||
_cairo_fixed_integer_part (tx),
|
||||
_cairo_fixed_integer_part (ty));
|
||||
}
|
||||
|
||||
if (clip->surface) {
|
||||
clip->surface_rect.x += _cairo_fixed_integer_part (tx);
|
||||
clip->surface_rect.y += _cairo_fixed_integer_part (ty);
|
||||
}
|
||||
|
||||
if (clip->path) {
|
||||
cairo_clip_path_t *clip_path = clip->path;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
cairo_matrix_init_translate (&matrix,
|
||||
_cairo_fixed_to_double (tx),
|
||||
_cairo_fixed_to_double (ty));
|
||||
|
||||
while (clip_path) {
|
||||
_cairo_path_fixed_transform (&clip_path->path, &matrix);
|
||||
clip_path = clip_path->prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_path_reapply_clip_path (cairo_clip_t *clip,
|
||||
cairo_clip_path_t *clip_path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip_path->prev) {
|
||||
status = _cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
|
||||
return _cairo_clip_intersect_path (clip,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
||||
cairo_clip_t *other,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_clip_init (clip, target);
|
||||
|
||||
if (other->mode != clip->mode) {
|
||||
/* We should reapply the original clip path in this case, and let
|
||||
* whatever the right handling is happen */
|
||||
} else {
|
||||
if (other->has_region) {
|
||||
status = _cairo_region_copy (&clip->region, &other->region);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
clip->has_region = TRUE;
|
||||
}
|
||||
|
||||
if (other->surface) {
|
||||
int dx, dy;
|
||||
status = _cairo_surface_clone_similar (target, other->surface,
|
||||
0,
|
||||
0,
|
||||
other->surface_rect.width,
|
||||
other->surface_rect.height,
|
||||
&dx, &dy,
|
||||
&clip->surface);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
clip->surface_rect = other->surface_rect;
|
||||
|
||||
/* src offset was 0, so we expect an exact replica of the surface */
|
||||
assert (dx == 0);
|
||||
assert (dy == 0);
|
||||
}
|
||||
|
||||
if (other->path) {
|
||||
status = _cairo_clip_path_reapply_clip_path (clip, other->path);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
BAIL:
|
||||
if (clip->has_region)
|
||||
_cairo_region_fini (&clip->region);
|
||||
if (clip->surface)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
const cairo_rectangle_list_t _cairo_rectangles_nil =
|
||||
{ CAIRO_STATUS_NO_MEMORY, NULL, 0 };
|
||||
static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
|
||||
{ CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
|
||||
cairo_rectangle_int_t *clip_rect,
|
||||
cairo_rectangle_t *user_rect)
|
||||
{
|
||||
cairo_bool_t is_tight;
|
||||
|
||||
double x1 = clip_rect->x;
|
||||
double y1 = clip_rect->y;
|
||||
double x2 = clip_rect->x + (int) clip_rect->width;
|
||||
double y2 = clip_rect->y + (int) clip_rect->height;
|
||||
|
||||
_cairo_gstate_backend_to_user_rectangle (gstate,
|
||||
&x1, &y1, &x2, &y2,
|
||||
&is_tight);
|
||||
|
||||
user_rect->x = x1;
|
||||
user_rect->y = y1;
|
||||
user_rect->width = x2 - x1;
|
||||
user_rect->height = y2 - y1;
|
||||
|
||||
return is_tight;
|
||||
}
|
||||
|
||||
cairo_rectangle_list_t *
|
||||
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles = NULL;
|
||||
int n_boxes = 0;
|
||||
|
||||
if (clip->all_clipped)
|
||||
goto DONE;
|
||||
|
||||
if (clip->path || clip->surface) {
|
||||
_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
cairo_box_int_t *boxes;
|
||||
int i;
|
||||
|
||||
if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes))
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
|
||||
if (n_boxes) {
|
||||
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL) {
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; ++i) {
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
clip_rect.x = boxes[i].p1.x;
|
||||
clip_rect.y = boxes[i].p1.y;
|
||||
clip_rect.width = boxes[i].p2.x - boxes[i].p1.x;
|
||||
clip_rect.height = boxes[i].p2.y - boxes[i].p1.y;
|
||||
|
||||
if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
|
||||
_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
} else {
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
n_boxes = 1;
|
||||
|
||||
rectangles = malloc(sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
|
||||
!_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
|
||||
{
|
||||
_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
list = malloc (sizeof (cairo_rectangle_list_t));
|
||||
if (list == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
list->status = CAIRO_STATUS_SUCCESS;
|
||||
list->rectangles = rectangles;
|
||||
list->num_rectangles = n_boxes;
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_rectangle_list_destroy:
|
||||
* @rectangle_list: a rectangle list, as obtained from cairo_copy_clip_rectangles()
|
||||
*
|
||||
* Unconditionally frees @rectangle_list and all associated
|
||||
* references. After this call, the @rectangle_list pointer must not
|
||||
* be dereferenced.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
void
|
||||
cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list)
|
||||
{
|
||||
if (rectangle_list == NULL || rectangle_list == &_cairo_rectangles_nil ||
|
||||
rectangle_list == &_cairo_rectangles_not_representable)
|
||||
return;
|
||||
|
||||
free (rectangle_list->rectangles);
|
||||
free (rectangle_list);
|
||||
}
|
||||
175
uppdev/plugin/cairo/lib/cairo-color.c
Normal file
175
uppdev/plugin/cairo/lib/cairo-color.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static cairo_color_t const cairo_color_white = {
|
||||
1.0, 1.0, 1.0, 1.0,
|
||||
0xffff, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
|
||||
static cairo_color_t const cairo_color_black = {
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
0x0, 0x0, 0x0, 0xffff
|
||||
};
|
||||
|
||||
static cairo_color_t const cairo_color_transparent = {
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
static cairo_color_t const cairo_color_magenta = {
|
||||
1.0, 0.0, 1.0, 1.0,
|
||||
0xffff, 0x0, 0xffff, 0xffff
|
||||
};
|
||||
|
||||
const cairo_color_t *
|
||||
_cairo_stock_color (cairo_stock_t stock)
|
||||
{
|
||||
switch (stock) {
|
||||
case CAIRO_STOCK_WHITE:
|
||||
return &cairo_color_white;
|
||||
case CAIRO_STOCK_BLACK:
|
||||
return &cairo_color_black;
|
||||
case CAIRO_STOCK_TRANSPARENT:
|
||||
return &cairo_color_transparent;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
|
||||
/* If the user can get here somehow, give a color that indicates a
|
||||
* problem. */
|
||||
return &cairo_color_magenta;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_init (cairo_color_t *color)
|
||||
{
|
||||
*color = cairo_color_white;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_init_rgb (cairo_color_t *color,
|
||||
double red, double green, double blue)
|
||||
{
|
||||
_cairo_color_init_rgba (color, red, green, blue, 1.0);
|
||||
}
|
||||
|
||||
/* Convert a double in [0.0, 1.0] to an integer in [0, 65535]
|
||||
* The conversion is designed to divide the input range into 65536
|
||||
* equally-sized regions. This is achieved by multiplying by 65536 and
|
||||
* then special-casing the result of an input value of 1.0 so that it
|
||||
* maps to 65535 instead of 65536.
|
||||
*/
|
||||
uint16_t
|
||||
_cairo_color_double_to_short (double d)
|
||||
{
|
||||
uint32_t i;
|
||||
i = (uint32_t) (d * 65536);
|
||||
i -= (i >> 16);
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_color_compute_shorts (cairo_color_t *color)
|
||||
{
|
||||
color->red_short = _cairo_color_double_to_short (color->red * color->alpha);
|
||||
color->green_short = _cairo_color_double_to_short (color->green * color->alpha);
|
||||
color->blue_short = _cairo_color_double_to_short (color->blue * color->alpha);
|
||||
color->alpha_short = _cairo_color_double_to_short (color->alpha);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_init_rgba (cairo_color_t *color,
|
||||
double red, double green, double blue,
|
||||
double alpha)
|
||||
{
|
||||
color->red = red;
|
||||
color->green = green;
|
||||
color->blue = blue;
|
||||
color->alpha = alpha;
|
||||
|
||||
_cairo_color_compute_shorts (color);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_multiply_alpha (cairo_color_t *color,
|
||||
double alpha)
|
||||
{
|
||||
color->alpha *= alpha;
|
||||
|
||||
_cairo_color_compute_shorts (color);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_get_rgba (cairo_color_t *color,
|
||||
double *red,
|
||||
double *green,
|
||||
double *blue,
|
||||
double *alpha)
|
||||
{
|
||||
*red = color->red;
|
||||
*green = color->green;
|
||||
*blue = color->blue;
|
||||
*alpha = color->alpha;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_get_rgba_premultiplied (cairo_color_t *color,
|
||||
double *red,
|
||||
double *green,
|
||||
double *blue,
|
||||
double *alpha)
|
||||
{
|
||||
*red = color->red * color->alpha;
|
||||
*green = color->green * color->alpha;
|
||||
*blue = color->blue * color->alpha;
|
||||
*alpha = color->alpha;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_color_equal (const cairo_color_t *color_a,
|
||||
const cairo_color_t *color_b)
|
||||
{
|
||||
if (color_a == color_b)
|
||||
return TRUE;
|
||||
|
||||
return color_a->red_short == color_b->red_short &&
|
||||
color_a->green_short == color_b->green_short &&
|
||||
color_a->blue_short == color_b->blue_short &&
|
||||
color_a->alpha_short == color_b->alpha_short;
|
||||
}
|
||||
162
uppdev/plugin/cairo/lib/cairo-compiler-private.h
Normal file
162
uppdev/plugin/cairo/lib/cairo-compiler-private.h
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_COMPILER_PRIVATE_H
|
||||
#define CAIRO_COMPILER_PRIVATE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
|
||||
# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_int_name(name) INT_##name
|
||||
# define slim_hidden_proto1(name, internal) \
|
||||
extern __typeof (name) name \
|
||||
__asm__ (slim_hidden_asmname (internal))
|
||||
# define slim_hidden_def1(name, internal) \
|
||||
extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \
|
||||
__attribute__((__alias__(slim_hidden_asmname(internal))))
|
||||
# define slim_hidden_ulp slim_hidden_ulp1(__USER_LABEL_PREFIX__)
|
||||
# define slim_hidden_ulp1(x) slim_hidden_ulp2(x)
|
||||
# define slim_hidden_ulp2(x) #x
|
||||
# define slim_hidden_asmname(name) slim_hidden_asmname1(name)
|
||||
# define slim_hidden_asmname1(name) slim_hidden_ulp #name
|
||||
#else
|
||||
# define slim_hidden_proto(name) int _cairo_dummy_prototype(void)
|
||||
# define slim_hidden_proto_no_warn(name) int _cairo_dummy_prototype(void)
|
||||
# define slim_hidden_def(name) int _cairo_dummy_prototype(void)
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
|
||||
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \
|
||||
__attribute__((__format__(__printf__, fmt_index, va_index)))
|
||||
#else
|
||||
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)
|
||||
#endif
|
||||
|
||||
/* slim_internal.h */
|
||||
#define CAIRO_HAS_HIDDEN_SYMBOLS 1
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
|
||||
#define cairo_private_no_warn __attribute__((__visibility__("hidden")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
#define cairo_private_no_warn __hidden
|
||||
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
|
||||
#define cairo_private_no_warn
|
||||
#undef CAIRO_HAS_HIDDEN_SYMBOLS
|
||||
#endif
|
||||
|
||||
#ifndef WARN_UNUSED_RESULT
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
/* Add attribute(warn_unused_result) if supported */
|
||||
#define cairo_warn WARN_UNUSED_RESULT
|
||||
#define cairo_private cairo_private_no_warn cairo_warn
|
||||
|
||||
/* This macro allow us to deprecate a function by providing an alias
|
||||
for the old function name to the new function name. With this
|
||||
macro, binary compatibility is preserved. The macro only works on
|
||||
some platforms --- tough.
|
||||
|
||||
Meanwhile, new definitions in the public header file break the
|
||||
source code so that it will no longer link against the old
|
||||
symbols. Instead it will give a descriptive error message
|
||||
indicating that the old function has been deprecated by the new
|
||||
function.
|
||||
*/
|
||||
#if __GNUC__ >= 2 && defined(__ELF__)
|
||||
# define CAIRO_FUNCTION_ALIAS(old, new) \
|
||||
extern __typeof (new) old \
|
||||
__asm__ ("" #old) \
|
||||
__attribute__((__alias__("" #new)))
|
||||
#else
|
||||
# define CAIRO_FUNCTION_ALIAS(old, new)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cairo uses the following function attributes in order to improve the
|
||||
* generated code (effectively by manual inter-procedural analysis).
|
||||
*
|
||||
* 'cairo_pure': The function is only allowed to read from its arguments
|
||||
* and global memory (i.e. following a pointer argument or
|
||||
* accessing a shared variable). The return value should
|
||||
* only depend on its arguments, and for an identical set of
|
||||
* arguments should return the same value.
|
||||
*
|
||||
* 'cairo_const': The function is only allowed to read from its arguments.
|
||||
* It is not allowed to access global memory. The return
|
||||
* value should only depend its arguments, and for an
|
||||
* identical set of arguments should return the same value.
|
||||
* This is currently the most strict function attribute.
|
||||
*
|
||||
* Both these function attributes allow gcc to perform CSE and
|
||||
* constant-folding, with 'cairo_const 'also guaranteeing that pointer contents
|
||||
* do not change across the function call.
|
||||
*/
|
||||
#if __GNUC__ >= 3
|
||||
#define cairo_pure __attribute__((pure))
|
||||
#define cairo_const __attribute__((const))
|
||||
#else
|
||||
#define cairo_pure
|
||||
#define cairo_const
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
#undef __attribute__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
|
||||
#define snprintf _snprintf
|
||||
#define popen _popen
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#undef inline
|
||||
#define inline __inline__
|
||||
#endif
|
||||
|
||||
#endif
|
||||
75
uppdev/plugin/cairo/lib/cairo-debug.c
Normal file
75
uppdev/plugin/cairo/lib/cairo-debug.c
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/**
|
||||
* cairo_debug_reset_static_data:
|
||||
*
|
||||
* Resets all static data within cairo to its original state,
|
||||
* (ie. identical to the state at the time of program invocation). For
|
||||
* example, all caches within cairo will be flushed empty.
|
||||
*
|
||||
* This function is intended to be useful when using memory-checking
|
||||
* tools such as valgrind. When valgrind's memcheck analyzes a
|
||||
* cairo-using program without a call to cairo_debug_reset_static_data(),
|
||||
* it will report all data reachable via cairo's static objects as
|
||||
* "still reachable". Calling cairo_debug_reset_static_data() just prior
|
||||
* to program termination will make it easier to get squeaky clean
|
||||
* reports from valgrind.
|
||||
*
|
||||
* WARNING: It is only safe to call this function when there are no
|
||||
* active cairo objects remaining, (ie. the appropriate destroy
|
||||
* functions have been called as necessary). If there are active cairo
|
||||
* objects, this call is likely to cause a crash, (eg. an assertion
|
||||
* failure due to a hash table being destroyed when non-empty).
|
||||
**/
|
||||
void
|
||||
cairo_debug_reset_static_data (void)
|
||||
{
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
_cairo_font_face_reset_static_data ();
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
_cairo_ft_font_reset_static_data ();
|
||||
#endif
|
||||
|
||||
_cairo_scaled_font_reset_static_data ();
|
||||
|
||||
_cairo_pattern_reset_static_data ();
|
||||
|
||||
CAIRO_MUTEX_FINALIZE ();
|
||||
}
|
||||
149
uppdev/plugin/cairo/lib/cairo-deflate-stream.c
Normal file
149
uppdev/plugin/cairo/lib/cairo-deflate-stream.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Adrian Johnson.
|
||||
*
|
||||
* Author(s):
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#define BUFFER_SIZE 16384
|
||||
|
||||
typedef struct _cairo_deflate_stream {
|
||||
cairo_output_stream_t base;
|
||||
cairo_output_stream_t *output;
|
||||
z_stream zlib_stream;
|
||||
unsigned char input_buf[BUFFER_SIZE];
|
||||
unsigned char output_buf[BUFFER_SIZE];
|
||||
} cairo_deflate_stream_t;
|
||||
|
||||
static void
|
||||
cairo_deflate_stream_deflate (cairo_deflate_stream_t *stream, cairo_bool_t flush)
|
||||
{
|
||||
int ret;
|
||||
cairo_bool_t finished;
|
||||
|
||||
do {
|
||||
ret = deflate (&stream->zlib_stream, flush ? Z_FINISH : Z_NO_FLUSH);
|
||||
if (flush || stream->zlib_stream.avail_out == 0)
|
||||
{
|
||||
_cairo_output_stream_write (stream->output,
|
||||
stream->output_buf,
|
||||
BUFFER_SIZE - stream->zlib_stream.avail_out);
|
||||
stream->zlib_stream.next_out = stream->output_buf;
|
||||
stream->zlib_stream.avail_out = BUFFER_SIZE;
|
||||
}
|
||||
|
||||
finished = TRUE;
|
||||
if (stream->zlib_stream.avail_in != 0)
|
||||
finished = FALSE;
|
||||
if (flush && ret != Z_STREAM_END)
|
||||
finished = FALSE;
|
||||
|
||||
} while (!finished);
|
||||
|
||||
stream->zlib_stream.next_in = stream->input_buf;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_deflate_stream_write (cairo_output_stream_t *base,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
cairo_deflate_stream_t *stream = (cairo_deflate_stream_t *) base;
|
||||
unsigned int count;
|
||||
const unsigned char *p = data;
|
||||
|
||||
while (length) {
|
||||
count = length;
|
||||
if (count > BUFFER_SIZE - stream->zlib_stream.avail_in)
|
||||
count = BUFFER_SIZE - stream->zlib_stream.avail_in;
|
||||
memcpy (stream->input_buf + stream->zlib_stream.avail_in, p, count);
|
||||
p += count;
|
||||
stream->zlib_stream.avail_in += count;
|
||||
length -= count;
|
||||
|
||||
if (stream->zlib_stream.avail_in == BUFFER_SIZE)
|
||||
cairo_deflate_stream_deflate (stream, FALSE);
|
||||
}
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_deflate_stream_close (cairo_output_stream_t *base)
|
||||
{
|
||||
cairo_deflate_stream_t *stream = (cairo_deflate_stream_t *) base;
|
||||
|
||||
cairo_deflate_stream_deflate (stream, TRUE);
|
||||
deflateEnd (&stream->zlib_stream);
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_deflate_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
cairo_deflate_stream_t *stream;
|
||||
|
||||
if (output->status)
|
||||
return _cairo_output_stream_create_in_error (output->status);
|
||||
|
||||
stream = malloc (sizeof (cairo_deflate_stream_t));
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base,
|
||||
_cairo_deflate_stream_write,
|
||||
_cairo_deflate_stream_close);
|
||||
stream->output = output;
|
||||
|
||||
stream->zlib_stream.zalloc = Z_NULL;
|
||||
stream->zlib_stream.zfree = Z_NULL;
|
||||
stream->zlib_stream.opaque = Z_NULL;
|
||||
|
||||
if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
|
||||
free (stream);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
stream->zlib_stream.next_in = stream->input_buf;
|
||||
stream->zlib_stream.avail_in = 0;
|
||||
stream->zlib_stream.next_out = stream->output_buf;
|
||||
stream->zlib_stream.avail_out = BUFFER_SIZE;
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
138
uppdev/plugin/cairo/lib/cairo-deprecated.h
Normal file
138
uppdev/plugin/cairo/lib/cairo-deprecated.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_DEPRECATED_H
|
||||
#define CAIRO_DEPRECATED_H
|
||||
|
||||
/* The %CAIRO_FORMAT_RGB16_565 value was added in cairo 1.2.0 as part
|
||||
* of fixing cairo's xlib backend to work with X servers advertising a
|
||||
* 16-bit, 565 visual. But as it turned out, adding this format to
|
||||
* #cairo_format_t was not necessary, and was a mistake, (cairo's xlib
|
||||
* backend can work fine with 16-bit visuals in the same way it works
|
||||
* with BGR visuals without any BGR formats in
|
||||
* #cairo_format_t).
|
||||
*
|
||||
* Additionally, the support for the RGB16_565 format was never
|
||||
* completely implemented. So while this format value is currently
|
||||
* deprecated, it may eventually acquire complete support in the future.
|
||||
*/
|
||||
#define CAIRO_FORMAT_RGB16_565 4
|
||||
|
||||
#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
|
||||
|
||||
/* Obsolete functions. These definitions exist to coerce the compiler
|
||||
* into providing a little bit of guidance with its error
|
||||
* messages. The idea is to help users port their old code without
|
||||
* having to dig through lots of documentation.
|
||||
*
|
||||
* The first set of REPLACED_BY functions is for functions whose names
|
||||
* have just been changed. So fixing these up is mechanical, (and
|
||||
* automated by means of the cairo/util/cairo-api-update script.
|
||||
*
|
||||
* The second set of DEPRECATED_BY functions is for functions where
|
||||
* the replacement is used in a different way, (ie. different
|
||||
* arguments, multiple functions instead of one, etc). Fixing these up
|
||||
* will require a bit more work on the user's part, (and hopefully we
|
||||
* can get cairo-api-update to find these and print some guiding
|
||||
* information).
|
||||
*/
|
||||
#define cairo_current_font_extents cairo_current_font_extents_REPLACED_BY_cairo_font_extents
|
||||
#define cairo_get_font_extents cairo_get_font_extents_REPLACED_BY_cairo_font_extents
|
||||
#define cairo_current_operator cairo_current_operator_REPLACED_BY_cairo_get_operator
|
||||
#define cairo_current_tolerance cairo_current_tolerance_REPLACED_BY_cairo_get_tolerance
|
||||
#define cairo_current_point cairo_current_point_REPLACED_BY_cairo_get_current_point
|
||||
#define cairo_current_fill_rule cairo_current_fill_rule_REPLACED_BY_cairo_get_fill_rule
|
||||
#define cairo_current_line_width cairo_current_line_width_REPLACED_BY_cairo_get_line_width
|
||||
#define cairo_current_line_cap cairo_current_line_cap_REPLACED_BY_cairo_get_line_cap
|
||||
#define cairo_current_line_join cairo_current_line_join_REPLACED_BY_cairo_get_line_join
|
||||
#define cairo_current_miter_limit cairo_current_miter_limit_REPLACED_BY_cairo_get_miter_limit
|
||||
#define cairo_current_matrix cairo_current_matrix_REPLACED_BY_cairo_get_matrix
|
||||
#define cairo_current_target_surface cairo_current_target_surface_REPLACED_BY_cairo_get_target
|
||||
#define cairo_get_status cairo_get_status_REPLACED_BY_cairo_status
|
||||
#define cairo_concat_matrix cairo_concat_matrix_REPLACED_BY_cairo_transform
|
||||
#define cairo_scale_font cairo_scale_font_REPLACED_BY_cairo_set_font_size
|
||||
#define cairo_select_font cairo_select_font_REPLACED_BY_cairo_select_font_face
|
||||
#define cairo_transform_font cairo_transform_font_REPLACED_BY_cairo_set_font_matrix
|
||||
#define cairo_transform_point cairo_transform_point_REPLACED_BY_cairo_user_to_device
|
||||
#define cairo_transform_distance cairo_transform_distance_REPLACED_BY_cairo_user_to_device_distance
|
||||
#define cairo_inverse_transform_point cairo_inverse_transform_point_REPLACED_BY_cairo_device_to_user
|
||||
#define cairo_inverse_transform_distance cairo_inverse_transform_distance_REPLACED_BY_cairo_device_to_user_distance
|
||||
#define cairo_init_clip cairo_init_clip_REPLACED_BY_cairo_reset_clip
|
||||
#define cairo_surface_create_for_image cairo_surface_create_for_image_REPLACED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_default_matrix cairo_default_matrix_REPLACED_BY_cairo_identity_matrix
|
||||
#define cairo_matrix_set_affine cairo_matrix_set_affine_REPLACED_BY_cairo_matrix_init
|
||||
#define cairo_matrix_set_identity cairo_matrix_set_identity_REPLACED_BY_cairo_matrix_init_identity
|
||||
#define cairo_pattern_add_color_stop cairo_pattern_add_color_stop_REPLACED_BY_cairo_pattern_add_color_stop_rgba
|
||||
#define cairo_set_rgb_color cairo_set_rgb_color_REPLACED_BY_cairo_set_source_rgb
|
||||
#define cairo_set_pattern cairo_set_pattern_REPLACED_BY_cairo_set_source
|
||||
#define cairo_xlib_surface_create_for_pixmap_with_visual cairo_xlib_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xlib_surface_create
|
||||
#define cairo_xlib_surface_create_for_window_with_visual cairo_xlib_surface_create_for_window_with_visual_REPLACED_BY_cairo_xlib_surface_create
|
||||
#define cairo_xcb_surface_create_for_pixmap_with_visual cairo_xcb_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xcb_surface_create
|
||||
#define cairo_xcb_surface_create_for_window_with_visual cairo_xcb_surface_create_for_window_with_visual_REPLACED_BY_cairo_xcb_surface_create
|
||||
#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_atsui_font_face_create_for_atsu_font_id cairo_atsui_font_face_create_for_atsu_font_id_REPLACED_BY_cairo_quartz_font_face_create_for_atsu_font_id
|
||||
|
||||
#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path
|
||||
#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat
|
||||
#define cairo_get_path cairo_get_path_DEPRECATED_BY_cairo_copy_path
|
||||
#define cairo_get_path_flat cairo_get_path_flat_DEPRECATED_BY_cairo_get_path_flat
|
||||
#define cairo_set_alpha cairo_set_alpha_DEPRECATED_BY_cairo_set_source_rgba_OR_cairo_paint_with_alpha
|
||||
#define cairo_show_surface cairo_show_surface_DEPRECATED_BY_cairo_set_source_surface_AND_cairo_paint
|
||||
#define cairo_copy cairo_copy_DEPRECATED_BY_cairo_create_AND_MANY_INDIVIDUAL_FUNCTIONS
|
||||
#define cairo_surface_set_repeat cairo_surface_set_repeat_DEPRECATED_BY_cairo_pattern_set_extend
|
||||
#define cairo_surface_set_matrix cairo_surface_set_matrix_DEPRECATED_BY_cairo_pattern_set_matrix
|
||||
#define cairo_surface_get_matrix cairo_surface_get_matrix_DEPRECATED_BY_cairo_pattern_get_matrix
|
||||
#define cairo_surface_set_filter cairo_surface_set_filter_DEPRECATED_BY_cairo_pattern_set_filter
|
||||
#define cairo_surface_get_filter cairo_surface_get_filter_DEPRECATED_BY_cairo_pattern_get_filter
|
||||
#define cairo_matrix_create cairo_matrix_create_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_destroy cairo_matrix_destroy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_copy cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_get_affine cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_set_target_surface cairo_set_target_surface_DEPRECATED_BY_cairo_create
|
||||
#define cairo_set_target_glitz cairo_set_target_glitz_DEPRECATED_BY_cairo_glitz_surface_create
|
||||
#define cairo_set_target_image cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_set_target_pdf cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create
|
||||
#define cairo_set_target_png cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png
|
||||
#define cairo_set_target_ps cairo_set_target_ps_DEPRECATED_BY_cairo_ps_surface_create
|
||||
#define cairo_set_target_quartz cairo_set_target_quartz_DEPRECATED_BY_cairo_quartz_surface_create
|
||||
#define cairo_set_target_win32 cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create
|
||||
#define cairo_set_target_xcb cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create
|
||||
#define cairo_set_target_drawable cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create
|
||||
#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
|
||||
#define cairo_status_string cairo_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
|
||||
|
||||
#endif /* CAIRO_DEPRECATED_H */
|
||||
1932
uppdev/plugin/cairo/lib/cairo-directfb-surface.c
Normal file
1932
uppdev/plugin/cairo/lib/cairo-directfb-surface.c
Normal file
File diff suppressed because it is too large
Load diff
67
uppdev/plugin/cairo/lib/cairo-directfb.h
Normal file
67
uppdev/plugin/cairo/lib/cairo-directfb.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@isi.edu>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Environment variables affecting the backend:
|
||||
*
|
||||
* %CAIRO_DIRECTFB_NO_ACCEL (boolean)
|
||||
* if found, disables acceleration at all
|
||||
*
|
||||
* %CAIRO_DIRECTFB_ARGB_FONT (boolean)
|
||||
* if found, enables using ARGB fonts instead of A8
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_DIRECTFB_H
|
||||
#define CAIRO_DIRECTFB_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_DIRECTFB_SURFACE
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /*CAIRO_HAS_DIRECTFB_SURFACE*/
|
||||
# error Cairo was not compiled with support for the directfb backend
|
||||
#endif /*CAIRO_HAS_DIRECTFB_SURFACE*/
|
||||
|
||||
#endif /*CAIRO_DIRECTFB_H*/
|
||||
28
uppdev/plugin/cairo/lib/cairo-features.h
Normal file
28
uppdev/plugin/cairo/lib/cairo-features.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Generated by configure. Do not edit. */
|
||||
#ifndef CAIRO_FEATURES_H
|
||||
#define CAIRO_FEATURES_H
|
||||
|
||||
#define CAIRO_HAS_IMAGE_SURFACE 1
|
||||
#define CAIRO_HAS_PDF_SURFACE 1
|
||||
#define CAIRO_HAS_PNG_FUNCTIONS 1
|
||||
//#define CAIRO_HAS_PS_SURFACE 1
|
||||
#define CAIRO_HAS_SVG_SURFACE 1
|
||||
//#define CAIRO_HAS_USER_FONT 1
|
||||
|
||||
/*#undef CAIRO_HAS_QUARTZ_FONT */
|
||||
/*#undef CAIRO_HAS_QUARTZ_SURFACE */
|
||||
|
||||
#ifndef cairo_public
|
||||
#define cairo_public
|
||||
#endif
|
||||
|
||||
#ifdef flagWIN32
|
||||
#define CAIRO_HAS_WIN32_SURFACE 1
|
||||
#define CAIRO_HAS_WIN32_FONT 1
|
||||
#else
|
||||
#define CAIRO_HAS_XLIB_SURFACE 1
|
||||
#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1
|
||||
#define CAIRO_HAS_FT_FONT 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
244
uppdev/plugin/cairo/lib/cairo-fixed-private.h
Normal file
244
uppdev/plugin/cairo/lib/cairo-fixed-private.h
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_FIXED_PRIVATE_H
|
||||
#define CAIRO_FIXED_PRIVATE_H
|
||||
|
||||
#include "cairo-fixed-type-private.h"
|
||||
|
||||
#include "cairo-wideint-private.h"
|
||||
|
||||
/* Implementation */
|
||||
|
||||
#if (CAIRO_FIXED_BITS != 32)
|
||||
# error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type.
|
||||
# error To remove this limitation, you will have to fix the tesselator.
|
||||
#endif
|
||||
|
||||
#define CAIRO_FIXED_ONE ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS))
|
||||
#define CAIRO_FIXED_ONE_DOUBLE ((double)(1 << CAIRO_FIXED_FRAC_BITS))
|
||||
#define CAIRO_FIXED_EPSILON ((cairo_fixed_t)(1))
|
||||
|
||||
#define CAIRO_FIXED_FRAC_MASK (((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS))
|
||||
#define CAIRO_FIXED_WHOLE_MASK (~CAIRO_FIXED_FRAC_MASK)
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_from_int (int i)
|
||||
{
|
||||
return i << CAIRO_FIXED_FRAC_BITS;
|
||||
}
|
||||
|
||||
/* This is the "magic number" approach to converting a double into fixed
|
||||
* point as described here:
|
||||
*
|
||||
* http://www.stereopsis.com/sree/fpu2006.html (an overview)
|
||||
* http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail)
|
||||
*
|
||||
* The basic idea is to add a large enough number to the double that the
|
||||
* literal floating point is moved up to the extent that it forces the
|
||||
* double's value to be shifted down to the bottom of the mantissa (to make
|
||||
* room for the large number being added in). Since the mantissa is, at a
|
||||
* given moment in time, a fixed point integer itself, one can convert a
|
||||
* float to various fixed point representations by moving around the point
|
||||
* of a floating point number through arithmetic operations. This behavior
|
||||
* is reliable on most modern platforms as it is mandated by the IEEE-754
|
||||
* standard for floating point arithmetic.
|
||||
*
|
||||
* For our purposes, a "magic number" must be carefully selected that is
|
||||
* both large enough to produce the desired point-shifting effect, and also
|
||||
* has no lower bits in its representation that would interfere with our
|
||||
* value at the bottom of the mantissa. The magic number is calculated as
|
||||
* follows:
|
||||
*
|
||||
* (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5
|
||||
*
|
||||
* where in our case:
|
||||
* - MANTISSA_SIZE for 64-bit doubles is 52
|
||||
* - FRACTIONAL_SIZE for 16.16 fixed point is 16
|
||||
*
|
||||
* Although this approach provides a very large speedup of this function
|
||||
* on a wide-array of systems, it does come with two caveats:
|
||||
*
|
||||
* 1) It uses banker's rounding as opposed to arithmetic rounding.
|
||||
* 2) It doesn't function properly if the FPU is in single-precision
|
||||
* mode.
|
||||
*/
|
||||
|
||||
/* The 16.16 number must always be available */
|
||||
#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0)
|
||||
|
||||
#if CAIRO_FIXED_BITS <= 32
|
||||
#define CAIRO_MAGIC_NUMBER_FIXED ((1LL << (52 - CAIRO_FIXED_FRAC_BITS)) * 1.5)
|
||||
|
||||
/* For 32-bit fixed point numbers */
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_from_double (double d)
|
||||
{
|
||||
union {
|
||||
double d;
|
||||
int32_t i[2];
|
||||
} u;
|
||||
|
||||
u.d = d + CAIRO_MAGIC_NUMBER_FIXED;
|
||||
#ifdef FLOAT_WORDS_BIGENDIAN
|
||||
return u.i[1];
|
||||
#else
|
||||
return u.i[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
# error Please define a magic number for your fixed point type!
|
||||
# error See cairo-fixed-private.h for details.
|
||||
#endif
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_from_26_6 (uint32_t i)
|
||||
{
|
||||
#if CAIRO_FIXED_FRAC_BITS > 6
|
||||
return i << (CAIRO_FIXED_FRAC_BITS - 6);
|
||||
#else
|
||||
return i >> (6 - CAIRO_FIXED_FRAC_BITS);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline double
|
||||
_cairo_fixed_to_double (cairo_fixed_t f)
|
||||
{
|
||||
return ((double) f) / CAIRO_FIXED_ONE_DOUBLE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_is_integer (cairo_fixed_t f)
|
||||
{
|
||||
return (f & CAIRO_FIXED_FRAC_MASK) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_part (cairo_fixed_t f)
|
||||
{
|
||||
return f >> CAIRO_FIXED_FRAC_BITS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_floor (cairo_fixed_t f)
|
||||
{
|
||||
if (f >= 0)
|
||||
return f >> CAIRO_FIXED_FRAC_BITS;
|
||||
else
|
||||
return -((-f - 1) >> CAIRO_FIXED_FRAC_BITS) - 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_ceil (cairo_fixed_t f)
|
||||
{
|
||||
if (f > 0)
|
||||
return ((f - 1)>>CAIRO_FIXED_FRAC_BITS) + 1;
|
||||
else
|
||||
return - (-f >> CAIRO_FIXED_FRAC_BITS);
|
||||
}
|
||||
|
||||
/* A bunch of explicit 16.16 operators; we need these
|
||||
* to interface with pixman and other backends that require
|
||||
* 16.16 fixed point types.
|
||||
*/
|
||||
static inline cairo_fixed_16_16_t
|
||||
_cairo_fixed_to_16_16 (cairo_fixed_t f)
|
||||
{
|
||||
#if (CAIRO_FIXED_FRAC_BITS == 16) && (CAIRO_FIXED_BITS == 32)
|
||||
return f;
|
||||
#elif CAIRO_FIXED_FRAC_BITS > 16
|
||||
/* We're just dropping the low bits, so we won't ever got over/underflow here */
|
||||
return f >> (CAIRO_FIXED_FRAC_BITS - 16);
|
||||
#else
|
||||
cairo_fixed_16_16_t x;
|
||||
|
||||
/* Handle overflow/underflow by clamping to the lowest/highest
|
||||
* value representable as 16.16
|
||||
*/
|
||||
if ((f >> CAIRO_FIXED_FRAC_BITS) < INT16_MIN) {
|
||||
x = INT32_MIN;
|
||||
} else if ((f >> CAIRO_FIXED_FRAC_BITS) > INT16_MAX) {
|
||||
x = INT32_MAX;
|
||||
} else {
|
||||
x = f << (16 - CAIRO_FIXED_FRAC_BITS);
|
||||
}
|
||||
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline cairo_fixed_16_16_t
|
||||
_cairo_fixed_16_16_from_double (double d)
|
||||
{
|
||||
union {
|
||||
double d;
|
||||
int32_t i[2];
|
||||
} u;
|
||||
|
||||
u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16;
|
||||
#ifdef FLOAT_WORDS_BIGENDIAN
|
||||
return u.i[1];
|
||||
#else
|
||||
return u.i[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CAIRO_FIXED_BITS == 32
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_mul (cairo_fixed_t a, cairo_fixed_t b)
|
||||
{
|
||||
cairo_int64_t temp = _cairo_int32x32_64_mul (a, b);
|
||||
return _cairo_int64_to_int32(_cairo_int64_rsl (temp, CAIRO_FIXED_FRAC_BITS));
|
||||
}
|
||||
|
||||
/* computes a * b / c */
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_mul_div (cairo_fixed_t a, cairo_fixed_t b, cairo_fixed_t c)
|
||||
{
|
||||
cairo_int64_t ab = _cairo_int32x32_64_mul (a, b);
|
||||
cairo_int64_t c64 = _cairo_int32_to_int64 (c);
|
||||
cairo_int64_t quo = _cairo_int64_divrem (ab, c64).quo;
|
||||
|
||||
return _cairo_int64_to_int32(quo);
|
||||
}
|
||||
|
||||
#else
|
||||
# error Please define multiplication and other operands for your fixed-point type size
|
||||
#endif
|
||||
|
||||
#endif /* CAIRO_FIXED_PRIVATE_H */
|
||||
70
uppdev/plugin/cairo/lib/cairo-fixed-type-private.h
Normal file
70
uppdev/plugin/cairo/lib/cairo-fixed-type-private.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_FIXED_TYPE_PRIVATE_H
|
||||
#define CAIRO_FIXED_TYPE_PRIVATE_H
|
||||
|
||||
#include "cairo-wideint-type-private.h"
|
||||
|
||||
/*
|
||||
* Fixed-point configuration
|
||||
*/
|
||||
|
||||
typedef int32_t cairo_fixed_16_16_t;
|
||||
typedef cairo_int64_t cairo_fixed_32_32_t;
|
||||
typedef cairo_int64_t cairo_fixed_48_16_t;
|
||||
typedef cairo_int128_t cairo_fixed_64_64_t;
|
||||
typedef cairo_int128_t cairo_fixed_96_32_t;
|
||||
|
||||
/* Eventually, we should allow changing this, but I think
|
||||
* there are some assumptions in the tesselator about the
|
||||
* size of a fixed type. For now, it must be 32.
|
||||
*/
|
||||
#define CAIRO_FIXED_BITS 32
|
||||
|
||||
/* The number of fractional bits. Changing this involves
|
||||
* making sure that you compute a double-to-fixed magic number.
|
||||
* (see below).
|
||||
*/
|
||||
#define CAIRO_FIXED_FRAC_BITS 8
|
||||
|
||||
/* A signed type %CAIRO_FIXED_BITS in size; the main fixed point type */
|
||||
typedef int32_t cairo_fixed_t;
|
||||
|
||||
/* An unsigned type of the same size as #cairo_fixed_t */
|
||||
typedef uint32_t cairo_fixed_unsigned_t;
|
||||
|
||||
#endif /* CAIRO_FIXED_TYPE_PRIVATE_H */
|
||||
39
uppdev/plugin/cairo/lib/cairo-fixed.c
Normal file
39
uppdev/plugin/cairo/lib/cairo-fixed.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-fixed-private.h"
|
||||
1030
uppdev/plugin/cairo/lib/cairo-font-face-twin-data.c
Normal file
1030
uppdev/plugin/cairo/lib/cairo-font-face-twin-data.c
Normal file
File diff suppressed because it is too large
Load diff
209
uppdev/plugin/cairo/lib/cairo-font-face-twin.c
Normal file
209
uppdev/plugin/cairo/lib/cairo-font-face-twin.c
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Packard
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Behdad Esfahbod <behdad@behdad.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/*
|
||||
* This file implements a user-font rendering the decendant of the Hershey
|
||||
* font coded by Keith Packard for use in the Twin window system.
|
||||
* The actual font data is in cairo-font-face-twin-data.c
|
||||
*
|
||||
* Ported to cairo user font by Behdad Esfahbod.
|
||||
*/
|
||||
|
||||
|
||||
#define twin_glyph_left(g) ((g)[0])
|
||||
#define twin_glyph_right(g) ((g)[1])
|
||||
#define twin_glyph_ascent(g) ((g)[2])
|
||||
#define twin_glyph_descent(g) ((g)[3])
|
||||
|
||||
#define twin_glyph_n_snap_x(g) ((g)[4])
|
||||
#define twin_glyph_n_snap_y(g) ((g)[5])
|
||||
#define twin_glyph_snap_x(g) (&g[6])
|
||||
#define twin_glyph_snap_y(g) (twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g))
|
||||
#define twin_glyph_draw(g) (twin_glyph_snap_y(g) + twin_glyph_n_snap_y(g))
|
||||
|
||||
#define SNAPI(p) (p)
|
||||
#define SNAPH(p) (p)
|
||||
|
||||
#define FX(g) ((g) / 64.)
|
||||
#define FY(g) ((g) / 64.)
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
twin_scaled_font_init (cairo_scaled_font_t *scaled_font,
|
||||
cairo_t *cr,
|
||||
cairo_font_extents_t *metrics)
|
||||
{
|
||||
metrics->ascent = FY (50);
|
||||
metrics->descent = FY (14);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
twin_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
|
||||
unsigned long unicode,
|
||||
unsigned long *glyph)
|
||||
{
|
||||
/* We use an identity charmap. Which means we could live
|
||||
* with no unicode_to_glyph method too. But we define this
|
||||
* to map all unknown chars to a single unknown glyph to
|
||||
* reduce pressure on cache. */
|
||||
|
||||
if (unicode < ARRAY_LENGTH (_cairo_twin_charmap))
|
||||
*glyph = unicode;
|
||||
else
|
||||
*glyph = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define SNAPX(p) _twin_snap (p, info.snap_x, info.n_snap_x)
|
||||
#define SNAPY(p) _twin_snap (p, info.snap_y, info.n_snap_y)
|
||||
|
||||
static double
|
||||
_twin_snap (double v, int a, int b)
|
||||
{
|
||||
return v; /* XXX */
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
|
||||
unsigned long glyph,
|
||||
cairo_t *cr,
|
||||
cairo_text_extents_t *metrics)
|
||||
{
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
const int8_t *b = _cairo_twin_outlines +
|
||||
_cairo_twin_charmap[glyph >= ARRAY_LENGTH (_cairo_twin_charmap) ? 0 : glyph];
|
||||
const int8_t *g = twin_glyph_draw(b);
|
||||
|
||||
struct {
|
||||
cairo_bool_t snap;
|
||||
int snap_x;
|
||||
int snap_y;
|
||||
int n_snap_x;
|
||||
int n_snap_y;
|
||||
} info = {FALSE};
|
||||
|
||||
cairo_set_line_width (cr, 0.06);
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
|
||||
for (;;) {
|
||||
switch (*g++) {
|
||||
case 'M':
|
||||
cairo_close_path (cr);
|
||||
/* fall through */
|
||||
case 'm':
|
||||
x1 = FX(*g++);
|
||||
y1 = FY(*g++);
|
||||
if (info.snap)
|
||||
{
|
||||
x1 = SNAPX (x1);
|
||||
y1 = SNAPY (y1);
|
||||
}
|
||||
cairo_move_to (cr, x1, y1);
|
||||
continue;
|
||||
case 'L':
|
||||
cairo_close_path (cr);
|
||||
/* fall through */
|
||||
case 'l':
|
||||
x1 = FX(*g++);
|
||||
y1 = FY(*g++);
|
||||
if (info.snap)
|
||||
{
|
||||
x1 = SNAPX (x1);
|
||||
y1 = SNAPY (y1);
|
||||
}
|
||||
cairo_line_to (cr, x1, y1);
|
||||
continue;
|
||||
case 'C':
|
||||
cairo_close_path (cr);
|
||||
/* fall through */
|
||||
case 'c':
|
||||
x1 = FX(*g++);
|
||||
y1 = FY(*g++);
|
||||
x2 = FX(*g++);
|
||||
y2 = FY(*g++);
|
||||
x3 = FX(*g++);
|
||||
y3 = FY(*g++);
|
||||
if (info.snap)
|
||||
{
|
||||
x1 = SNAPX (x1);
|
||||
y1 = SNAPY (y1);
|
||||
x2 = SNAPX (x2);
|
||||
y2 = SNAPY (y2);
|
||||
x3 = SNAPX (x3);
|
||||
y3 = SNAPY (y3);
|
||||
}
|
||||
cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
|
||||
continue;
|
||||
case 'E':
|
||||
cairo_close_path (cr);
|
||||
/* fall through */
|
||||
case 'e':
|
||||
cairo_stroke (cr);
|
||||
break;
|
||||
case 'X':
|
||||
/* filler */
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
metrics->x_advance = FX(twin_glyph_right(b)) + cairo_get_line_width (cr);
|
||||
metrics->x_advance += cairo_get_line_width (cr)/* XXX 2*x.margin */;
|
||||
if (info.snap)
|
||||
metrics->x_advance = SNAPI (SNAPX (metrics->x_advance));
|
||||
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
_cairo_font_face_twin_create (cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight)
|
||||
{
|
||||
cairo_font_face_t *twin_font_face;
|
||||
|
||||
twin_font_face = cairo_user_font_face_create ();
|
||||
cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init);
|
||||
cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph);
|
||||
cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph);
|
||||
|
||||
return twin_font_face;
|
||||
}
|
||||
776
uppdev/plugin/cairo/lib/cairo-font-face.c
Normal file
776
uppdev/plugin/cairo/lib/cairo-font-face.c
Normal file
|
|
@ -0,0 +1,776 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
*/
|
||||
|
||||
#define _BSD_SOURCE /* for strdup() */
|
||||
#include "cairoint.h"
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
|
||||
|
||||
/* #cairo_font_face_t */
|
||||
|
||||
const cairo_toy_font_face_t _cairo_font_face_nil = {
|
||||
{
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
},
|
||||
CAIRO_FONT_FAMILY_DEFAULT, /* family */
|
||||
TRUE, /* owns_family */
|
||||
CAIRO_FONT_SLANT_DEFAULT, /* slant */
|
||||
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
|
||||
};
|
||||
|
||||
static const cairo_toy_font_face_t _cairo_font_face_null_pointer = {
|
||||
{
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_NULL_POINTER, /* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
},
|
||||
CAIRO_FONT_FAMILY_DEFAULT, /* family */
|
||||
TRUE, /* owns_family */
|
||||
CAIRO_FONT_SLANT_DEFAULT, /* slant */
|
||||
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
|
||||
};
|
||||
|
||||
static const cairo_toy_font_face_t _cairo_font_face_invalid_string = {
|
||||
{
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_INVALID_STRING, /* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
},
|
||||
CAIRO_FONT_FAMILY_DEFAULT, /* family */
|
||||
TRUE, /* owns_family */
|
||||
CAIRO_FONT_SLANT_DEFAULT, /* slant */
|
||||
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
|
||||
};
|
||||
|
||||
static const cairo_toy_font_face_t _cairo_font_face_invalid_slant = {
|
||||
{
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_INVALID_SLANT, /* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
},
|
||||
CAIRO_FONT_FAMILY_DEFAULT, /* family */
|
||||
TRUE, /* owns_family */
|
||||
CAIRO_FONT_SLANT_DEFAULT, /* slant */
|
||||
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
|
||||
};
|
||||
|
||||
static const cairo_toy_font_face_t _cairo_font_face_invalid_weight = {
|
||||
{
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_INVALID_WEIGHT, /* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
},
|
||||
CAIRO_FONT_FAMILY_DEFAULT, /* family */
|
||||
TRUE, /* owns_family */
|
||||
CAIRO_FONT_SLANT_DEFAULT, /* slant */
|
||||
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
|
||||
};
|
||||
|
||||
cairo_status_t
|
||||
_cairo_font_face_set_error (cairo_font_face_t *font_face,
|
||||
cairo_status_t status)
|
||||
{
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (&font_face->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_font_face_init (cairo_font_face_t *font_face,
|
||||
const cairo_font_face_backend_t *backend)
|
||||
{
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
font_face->status = CAIRO_STATUS_SUCCESS;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
|
||||
font_face->backend = backend;
|
||||
|
||||
_cairo_user_data_array_init (&font_face->user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_face_reference:
|
||||
* @font_face: a #cairo_font_face_t, (may be %NULL in which case this
|
||||
* function does nothing).
|
||||
*
|
||||
* Increases the reference count on @font_face by one. This prevents
|
||||
* @font_face from being destroyed until a matching call to
|
||||
* cairo_font_face_destroy() is made.
|
||||
*
|
||||
* The number of references to a #cairo_font_face_t can be get using
|
||||
* cairo_font_face_get_reference_count().
|
||||
*
|
||||
* Return value: the referenced #cairo_font_face_t.
|
||||
**/
|
||||
cairo_font_face_t *
|
||||
cairo_font_face_reference (cairo_font_face_t *font_face)
|
||||
{
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return font_face;
|
||||
|
||||
/* We would normally assert that we have a reference here but we
|
||||
* can't get away with that due to the zombie case as documented
|
||||
* in _cairo_ft_font_face_destroy. */
|
||||
|
||||
_cairo_reference_count_inc (&font_face->ref_count);
|
||||
|
||||
return font_face;
|
||||
}
|
||||
slim_hidden_def (cairo_font_face_reference);
|
||||
|
||||
/**
|
||||
* cairo_font_face_destroy:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
*
|
||||
* Decreases the reference count on @font_face by one. If the result
|
||||
* is zero, then @font_face and all associated resources are freed.
|
||||
* See cairo_font_face_reference().
|
||||
**/
|
||||
void
|
||||
cairo_font_face_destroy (cairo_font_face_t *font_face)
|
||||
{
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return;
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
|
||||
return;
|
||||
|
||||
if (font_face->backend->destroy)
|
||||
font_face->backend->destroy (font_face);
|
||||
|
||||
/* We allow resurrection to deal with some memory management for the
|
||||
* FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
|
||||
* need to effectively mutually reference each other
|
||||
*/
|
||||
if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
|
||||
return;
|
||||
|
||||
_cairo_user_data_array_fini (&font_face->user_data);
|
||||
|
||||
free (font_face);
|
||||
}
|
||||
slim_hidden_def (cairo_font_face_destroy);
|
||||
|
||||
/**
|
||||
* cairo_font_face_get_type:
|
||||
* @font_face: a font face
|
||||
*
|
||||
* This function returns the type of the backend used to create
|
||||
* a font face. See #cairo_font_type_t for available types.
|
||||
*
|
||||
* Return value: The type of @font_face.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
cairo_font_type_t
|
||||
cairo_font_face_get_type (cairo_font_face_t *font_face)
|
||||
{
|
||||
return font_face->backend->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_face_get_reference_count:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
*
|
||||
* Returns the current reference count of @font_face.
|
||||
*
|
||||
* Return value: the current reference count of @font_face. If the
|
||||
* object is a nil object, 0 will be returned.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
unsigned int
|
||||
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
|
||||
{
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return 0;
|
||||
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_face_status:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
*
|
||||
* Checks whether an error has previously occurred for this
|
||||
* font face
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or another error such as
|
||||
* %CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_font_face_status (cairo_font_face_t *font_face)
|
||||
{
|
||||
return font_face->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_face_get_user_data:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
* @key: the address of the #cairo_user_data_key_t the user data was
|
||||
* attached to
|
||||
*
|
||||
* Return user data previously attached to @font_face using the specified
|
||||
* key. If no user data has been attached with the given key this
|
||||
* function returns %NULL.
|
||||
*
|
||||
* Return value: the user data previously attached or %NULL.
|
||||
**/
|
||||
void *
|
||||
cairo_font_face_get_user_data (cairo_font_face_t *font_face,
|
||||
const cairo_user_data_key_t *key)
|
||||
{
|
||||
return _cairo_user_data_array_get_data (&font_face->user_data,
|
||||
key);
|
||||
}
|
||||
slim_hidden_def (cairo_font_face_get_user_data);
|
||||
|
||||
/**
|
||||
* cairo_font_face_set_user_data:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
* @key: the address of a #cairo_user_data_key_t to attach the user data to
|
||||
* @user_data: the user data to attach to the font face
|
||||
* @destroy: a #cairo_destroy_func_t which will be called when the
|
||||
* font face is destroyed or when new user data is attached using the
|
||||
* same key.
|
||||
*
|
||||
* Attach user data to @font_face. To remove user data from a font face,
|
||||
* call this function with the key that was used to set it and %NULL
|
||||
* for @data.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
|
||||
* slot could not be allocated for the user data.
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_font_face_set_user_data (cairo_font_face_t *font_face,
|
||||
const cairo_user_data_key_t *key,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return font_face->status;
|
||||
|
||||
return _cairo_user_data_array_set_data (&font_face->user_data,
|
||||
key, user_data, destroy);
|
||||
}
|
||||
slim_hidden_def (cairo_font_face_set_user_data);
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
|
||||
|
||||
static int
|
||||
_cairo_toy_font_face_keys_equal (const void *key_a,
|
||||
const void *key_b);
|
||||
|
||||
/* We maintain a hash table from family/weight/slant =>
|
||||
* #cairo_font_face_t for #cairo_toy_font_t. The primary purpose of
|
||||
* this mapping is to provide unique #cairo_font_face_t values so that
|
||||
* our cache and mapping from #cairo_font_face_t => #cairo_scaled_font_t
|
||||
* works. Once the corresponding #cairo_font_face_t objects fall out of
|
||||
* downstream caches, we don't need them in this hash table anymore.
|
||||
*
|
||||
* Modifications to this hash table are protected by
|
||||
* _cairo_font_face_mutex.
|
||||
*/
|
||||
static cairo_hash_table_t *cairo_toy_font_face_hash_table = NULL;
|
||||
|
||||
static cairo_hash_table_t *
|
||||
_cairo_toy_font_face_hash_table_lock (void)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
|
||||
|
||||
if (cairo_toy_font_face_hash_table == NULL)
|
||||
{
|
||||
cairo_toy_font_face_hash_table =
|
||||
_cairo_hash_table_create (_cairo_toy_font_face_keys_equal);
|
||||
|
||||
if (cairo_toy_font_face_hash_table == NULL) {
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return cairo_toy_font_face_hash_table;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_toy_font_face_hash_table_unlock (void)
|
||||
{
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_toy_font_face_init_key:
|
||||
*
|
||||
* Initialize those portions of #cairo_toy_font_face_t needed to use
|
||||
* it as a hash table key, including the hash code buried away in
|
||||
* font_face->base.hash_entry. No memory allocation is performed here
|
||||
* so that no fini call is needed. We do this to make it easier to use
|
||||
* an automatic #cairo_toy_font_face_t variable as a key.
|
||||
**/
|
||||
static void
|
||||
_cairo_toy_font_face_init_key (cairo_toy_font_face_t *key,
|
||||
const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight)
|
||||
{
|
||||
unsigned long hash;
|
||||
|
||||
key->family = family;
|
||||
key->owns_family = FALSE;
|
||||
|
||||
key->slant = slant;
|
||||
key->weight = weight;
|
||||
|
||||
/* 1607 and 1451 are just a couple of arbitrary primes. */
|
||||
hash = _cairo_hash_string (family);
|
||||
hash += ((unsigned long) slant) * 1607;
|
||||
hash += ((unsigned long) weight) * 1451;
|
||||
|
||||
assert (hash != 0);
|
||||
key->base.hash_entry.hash = hash;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
|
||||
const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight)
|
||||
{
|
||||
char *family_copy;
|
||||
|
||||
family_copy = strdup (family);
|
||||
if (family_copy == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_toy_font_face_init_key (font_face, family_copy,
|
||||
slant, weight);
|
||||
font_face->owns_family = TRUE;
|
||||
|
||||
_cairo_font_face_init (&font_face->base, &_cairo_toy_font_face_backend);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
|
||||
{
|
||||
/* We assert here that we own font_face->family before casting
|
||||
* away the const qualifer. */
|
||||
assert (font_face->owns_family);
|
||||
free ((char*) font_face->family);
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_toy_font_face_keys_equal (const void *key_a,
|
||||
const void *key_b)
|
||||
{
|
||||
const cairo_toy_font_face_t *face_a = key_a;
|
||||
const cairo_toy_font_face_t *face_b = key_b;
|
||||
|
||||
return (strcmp (face_a->family, face_b->family) == 0 &&
|
||||
face_a->slant == face_b->slant &&
|
||||
face_a->weight == face_b->weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_toy_font_face_create:
|
||||
* @family: a font family name, encoded in UTF-8
|
||||
* @slant: the slant for the font
|
||||
* @weight: the weight for the font
|
||||
*
|
||||
* Creates a font face from a triplet of family, slant, and weight.
|
||||
* These font faces are used in implementation of the the #cairo_t "toy"
|
||||
* font API.
|
||||
*
|
||||
* If @family is the zero-length string "", the platform-specific default
|
||||
* family is assumed. The default family then can be queried using
|
||||
* cairo_toy_font_face_get_family().
|
||||
*
|
||||
* The cairo_select_font_face() function uses this to create font faces.
|
||||
* See that function for limitations of toy font faces.
|
||||
*
|
||||
* Return value: a newly created #cairo_font_face_t. Free with
|
||||
* cairo_font_face_destroy() when you are done using it.
|
||||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
cairo_font_face_t *
|
||||
cairo_toy_font_face_create (const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_toy_font_face_t key, *font_face;
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
if (family == NULL)
|
||||
return (cairo_font_face_t*) &_cairo_font_face_null_pointer;
|
||||
|
||||
/* Make sure we've got valid UTF-8 for the family */
|
||||
status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL);
|
||||
if (status == CAIRO_STATUS_INVALID_STRING)
|
||||
return (cairo_font_face_t*) &_cairo_font_face_invalid_string;
|
||||
else if (status)
|
||||
return (cairo_font_face_t*) &_cairo_font_face_nil;
|
||||
|
||||
switch (slant) {
|
||||
case CAIRO_FONT_SLANT_NORMAL:
|
||||
case CAIRO_FONT_SLANT_ITALIC:
|
||||
case CAIRO_FONT_SLANT_OBLIQUE:
|
||||
break;
|
||||
default:
|
||||
return (cairo_font_face_t*) &_cairo_font_face_invalid_slant;
|
||||
}
|
||||
|
||||
switch (weight) {
|
||||
case CAIRO_FONT_WEIGHT_NORMAL:
|
||||
case CAIRO_FONT_WEIGHT_BOLD:
|
||||
break;
|
||||
default:
|
||||
return (cairo_font_face_t*) &_cairo_font_face_invalid_weight;
|
||||
}
|
||||
|
||||
if (*family == '\0')
|
||||
family = CAIRO_FONT_FAMILY_DEFAULT;
|
||||
|
||||
hash_table = _cairo_toy_font_face_hash_table_lock ();
|
||||
if (hash_table == NULL)
|
||||
goto UNWIND;
|
||||
|
||||
_cairo_toy_font_face_init_key (&key, family, slant, weight);
|
||||
|
||||
/* Return existing font_face if it exists in the hash table. */
|
||||
if (_cairo_hash_table_lookup (hash_table,
|
||||
&key.base.hash_entry,
|
||||
(cairo_hash_entry_t **) &font_face))
|
||||
{
|
||||
if (! font_face->base.status) {
|
||||
/* We increment the reference count here manually to avoid
|
||||
double-locking. */
|
||||
_cairo_reference_count_inc (&font_face->base.ref_count);
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
return &font_face->base;
|
||||
}
|
||||
|
||||
/* remove the bad font from the hash table */
|
||||
_cairo_hash_table_remove (hash_table, &key.base.hash_entry);
|
||||
font_face->base.hash_entry.hash = 0;
|
||||
}
|
||||
|
||||
/* Otherwise create it and insert into hash table. */
|
||||
font_face = malloc (sizeof (cairo_toy_font_face_t));
|
||||
if (font_face == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto UNWIND_HASH_TABLE_LOCK;
|
||||
}
|
||||
|
||||
status = _cairo_toy_font_face_init (font_face, family, slant, weight);
|
||||
if (status)
|
||||
goto UNWIND_FONT_FACE_MALLOC;
|
||||
|
||||
status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
|
||||
if (status)
|
||||
goto UNWIND_FONT_FACE_INIT;
|
||||
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
|
||||
return &font_face->base;
|
||||
|
||||
UNWIND_FONT_FACE_INIT:
|
||||
_cairo_toy_font_face_fini (font_face);
|
||||
UNWIND_FONT_FACE_MALLOC:
|
||||
free (font_face);
|
||||
UNWIND_HASH_TABLE_LOCK:
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
UNWIND:
|
||||
return (cairo_font_face_t*) &_cairo_font_face_nil;
|
||||
}
|
||||
slim_hidden_def (cairo_toy_font_face_create);
|
||||
|
||||
static void
|
||||
_cairo_toy_font_face_destroy (void *abstract_face)
|
||||
{
|
||||
cairo_toy_font_face_t *font_face = abstract_face;
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->base.ref_count))
|
||||
return;
|
||||
|
||||
hash_table = _cairo_toy_font_face_hash_table_lock ();
|
||||
/* All created objects must have been mapped in the hash table. */
|
||||
assert (hash_table != NULL);
|
||||
|
||||
if (font_face->base.hash_entry.hash != 0)
|
||||
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
|
||||
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
|
||||
_cairo_toy_font_face_fini (font_face);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_toy_font_face_scaled_font_get_implementation (void *abstract_font_face,
|
||||
cairo_font_face_t **font_face_out)
|
||||
{
|
||||
cairo_toy_font_face_t *font_face = abstract_font_face;
|
||||
cairo_status_t status;
|
||||
|
||||
if (font_face->base.status)
|
||||
return font_face->base.status;
|
||||
|
||||
if (CAIRO_SCALED_FONT_BACKEND_DEFAULT != &_cairo_user_scaled_font_backend)
|
||||
{
|
||||
const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
|
||||
|
||||
if (backend->get_implementation == NULL) {
|
||||
*font_face_out = &font_face->base;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = backend->get_implementation (font_face,
|
||||
font_face_out);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return _cairo_font_face_set_error (&font_face->base, status);
|
||||
}
|
||||
|
||||
status = _cairo_user_scaled_font_backend.get_implementation (font_face,
|
||||
font_face_out);
|
||||
|
||||
return _cairo_font_face_set_error (&font_face->base, status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_toy_font_face_scaled_font_create (void *abstract_font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font)
|
||||
{
|
||||
cairo_toy_font_face_t *font_face = abstract_font_face;
|
||||
cairo_status_t status;
|
||||
|
||||
if (font_face->base.status)
|
||||
return font_face->base.status;
|
||||
|
||||
status = cairo_font_options_status ((cairo_font_options_t *) options);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (CAIRO_SCALED_FONT_BACKEND_DEFAULT != &_cairo_user_scaled_font_backend)
|
||||
{
|
||||
const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
|
||||
|
||||
*scaled_font = NULL;
|
||||
status = backend->create_toy (font_face,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options,
|
||||
scaled_font);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return _cairo_font_face_set_error (&font_face->base, status);
|
||||
|
||||
if (*scaled_font)
|
||||
cairo_scaled_font_destroy (*scaled_font);
|
||||
}
|
||||
|
||||
status = _cairo_user_scaled_font_backend.create_toy (font_face,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options,
|
||||
scaled_font);
|
||||
|
||||
return _cairo_font_face_set_error (&font_face->base, status);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_font_face_is_toy (cairo_font_face_t *font_face)
|
||||
{
|
||||
return font_face->backend == &_cairo_toy_font_face_backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_toy_font_face_get_family:
|
||||
* @font_face: A toy font face
|
||||
*
|
||||
* Gets the familly name of a toy font.
|
||||
*
|
||||
* Return value: The family name. This string is owned by the font face
|
||||
* and remains valid as long as the font face is alive (referenced).
|
||||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
const char *
|
||||
cairo_toy_font_face_get_family (cairo_font_face_t *font_face)
|
||||
{
|
||||
cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
|
||||
if (! _cairo_font_face_is_toy (font_face)) {
|
||||
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
|
||||
return CAIRO_FONT_FAMILY_DEFAULT;
|
||||
}
|
||||
assert (toy_font_face->owns_family);
|
||||
return toy_font_face->family;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_toy_font_face_get_slant:
|
||||
* @font_face: A toy font face
|
||||
*
|
||||
* Gets the slant a toy font.
|
||||
*
|
||||
* Return value: The slant value
|
||||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
cairo_font_slant_t
|
||||
cairo_toy_font_face_get_slant (cairo_font_face_t *font_face)
|
||||
{
|
||||
cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
|
||||
if (! _cairo_font_face_is_toy (font_face)) {
|
||||
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
|
||||
return CAIRO_FONT_SLANT_DEFAULT;
|
||||
}
|
||||
return toy_font_face->slant;
|
||||
}
|
||||
slim_hidden_def (cairo_toy_font_face_get_slant);
|
||||
|
||||
/**
|
||||
* cairo_toy_font_face_get_weight:
|
||||
* @font_face: A toy font face
|
||||
*
|
||||
* Gets the weight a toy font.
|
||||
*
|
||||
* Return value: The weight value
|
||||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
cairo_font_weight_t
|
||||
cairo_toy_font_face_get_weight (cairo_font_face_t *font_face)
|
||||
{
|
||||
cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
|
||||
if (! _cairo_font_face_is_toy (font_face)) {
|
||||
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
|
||||
return CAIRO_FONT_WEIGHT_DEFAULT;
|
||||
}
|
||||
return toy_font_face->weight;
|
||||
}
|
||||
slim_hidden_def (cairo_toy_font_face_get_weight);
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
|
||||
CAIRO_FONT_TYPE_TOY,
|
||||
_cairo_toy_font_face_destroy,
|
||||
_cairo_toy_font_face_scaled_font_get_implementation,
|
||||
_cairo_toy_font_face_scaled_font_create
|
||||
};
|
||||
|
||||
void
|
||||
_cairo_unscaled_font_init (cairo_unscaled_font_t *unscaled_font,
|
||||
const cairo_unscaled_font_backend_t *backend)
|
||||
{
|
||||
CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
|
||||
unscaled_font->backend = backend;
|
||||
}
|
||||
|
||||
cairo_unscaled_font_t *
|
||||
_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
|
||||
{
|
||||
if (unscaled_font == NULL)
|
||||
return NULL;
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
|
||||
|
||||
_cairo_reference_count_inc (&unscaled_font->ref_count);
|
||||
|
||||
return unscaled_font;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
|
||||
{
|
||||
if (unscaled_font == NULL)
|
||||
return;
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
|
||||
return;
|
||||
|
||||
unscaled_font->backend->destroy (unscaled_font);
|
||||
|
||||
free (unscaled_font);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_font_face_reset_static_data (void)
|
||||
{
|
||||
_cairo_scaled_font_map_destroy ();
|
||||
|
||||
/* We manually acquire the lock rather than calling
|
||||
* cairo_toy_font_face_hash_table_lock simply to avoid
|
||||
* creating the table only to destroy it again. */
|
||||
CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
|
||||
_cairo_hash_table_destroy (cairo_toy_font_face_hash_table);
|
||||
cairo_toy_font_face_hash_table = NULL;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
|
||||
}
|
||||
406
uppdev/plugin/cairo/lib/cairo-font-options.c
Normal file
406
uppdev/plugin/cairo/lib/cairo-font-options.c
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static const cairo_font_options_t _cairo_font_options_nil = {
|
||||
CAIRO_ANTIALIAS_DEFAULT,
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT,
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
CAIRO_HINT_METRICS_DEFAULT
|
||||
};
|
||||
|
||||
/**
|
||||
* _cairo_font_options_init_default:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Initializes all fields of the font options object to default values.
|
||||
**/
|
||||
void
|
||||
_cairo_font_options_init_default (cairo_font_options_t *options)
|
||||
{
|
||||
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_font_options_init_copy (cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other)
|
||||
{
|
||||
options->antialias = other->antialias;
|
||||
options->subpixel_order = other->subpixel_order;
|
||||
options->hint_style = other->hint_style;
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_create:
|
||||
*
|
||||
* Allocates a new font options object with all options initialized
|
||||
* to default values.
|
||||
*
|
||||
* Return value: a newly allocated #cairo_font_options_t. Free with
|
||||
* cairo_font_options_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_font_options_status().
|
||||
**/
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_create (void)
|
||||
{
|
||||
cairo_font_options_t *options;
|
||||
|
||||
options = malloc (sizeof (cairo_font_options_t));
|
||||
if (!options) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_options_t *) &_cairo_font_options_nil;
|
||||
}
|
||||
|
||||
_cairo_font_options_init_default (options);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_copy:
|
||||
* @original: a #cairo_font_options_t
|
||||
*
|
||||
* Allocates a new font options object copying the option values from
|
||||
* @original.
|
||||
*
|
||||
* Return value: a newly allocated #cairo_font_options_t. Free with
|
||||
* cairo_font_options_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_font_options_status().
|
||||
**/
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_copy (const cairo_font_options_t *original)
|
||||
{
|
||||
cairo_font_options_t *options;
|
||||
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) original))
|
||||
return (cairo_font_options_t *) &_cairo_font_options_nil;
|
||||
|
||||
options = malloc (sizeof (cairo_font_options_t));
|
||||
if (!options) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_options_t *) &_cairo_font_options_nil;
|
||||
}
|
||||
|
||||
_cairo_font_options_init_copy (options, original);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_destroy:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Destroys a #cairo_font_options_t object created with with
|
||||
* cairo_font_options_create() or cairo_font_options_copy().
|
||||
**/
|
||||
void
|
||||
cairo_font_options_destroy (cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
free (options);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_status:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Checks whether an error has previously occurred for this
|
||||
* font options object
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_font_options_status (cairo_font_options_t *options)
|
||||
{
|
||||
if (options == NULL)
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
else if (options == (cairo_font_options_t *) &_cairo_font_options_nil)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
else
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_status);
|
||||
|
||||
/**
|
||||
* cairo_font_options_merge:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @other: another #cairo_font_options_t
|
||||
*
|
||||
* Merges non-default options from @other into @options, replacing
|
||||
* existing values. This operation can be thought of as somewhat
|
||||
* similar to compositing @other onto @options with the operation
|
||||
* of %CAIRO_OPERATION_OVER.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_merge (cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) other))
|
||||
return;
|
||||
|
||||
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
|
||||
options->antialias = other->antialias;
|
||||
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
|
||||
options->subpixel_order = other->subpixel_order;
|
||||
if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
|
||||
options->hint_style = other->hint_style;
|
||||
if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_merge);
|
||||
|
||||
/**
|
||||
* cairo_font_options_equal:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @other: another #cairo_font_options_t
|
||||
*
|
||||
* Compares two font options objects for equality.
|
||||
*
|
||||
* Return value: %TRUE if all fields of the two font options objects match.
|
||||
* Note that this function will return %FALSE if either object is in
|
||||
* error.
|
||||
**/
|
||||
cairo_bool_t
|
||||
cairo_font_options_equal (const cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return FALSE;
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) other))
|
||||
return FALSE;
|
||||
|
||||
if (options == other)
|
||||
return TRUE;
|
||||
|
||||
return (options->antialias == other->antialias &&
|
||||
options->subpixel_order == other->subpixel_order &&
|
||||
options->hint_style == other->hint_style &&
|
||||
options->hint_metrics == other->hint_metrics);
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_equal);
|
||||
|
||||
/**
|
||||
* cairo_font_options_hash:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Compute a hash for the font options object; this value will
|
||||
* be useful when storing an object containing a #cairo_font_options_t
|
||||
* in a hash table.
|
||||
*
|
||||
* Return value: the hash value for the font options object.
|
||||
* The return value can be cast to a 32-bit type if a
|
||||
* 32-bit hash value is needed.
|
||||
**/
|
||||
unsigned long
|
||||
cairo_font_options_hash (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
options = &_cairo_font_options_nil; /* force default values */
|
||||
|
||||
return ((options->antialias) |
|
||||
(options->subpixel_order << 4) |
|
||||
(options->hint_style << 8) |
|
||||
(options->hint_metrics << 16));
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_hash);
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_antialias:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @antialias: the new antialiasing mode
|
||||
*
|
||||
* Sets the antialiasing mode for the font options object. This
|
||||
* specifies the type of antialiasing to do when rendering text.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_antialias (cairo_font_options_t *options,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
options->antialias = antialias;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_antialias);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_antialias:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the antialiasing mode for the font options object.
|
||||
*
|
||||
* Return value: the antialiasing mode
|
||||
**/
|
||||
cairo_antialias_t
|
||||
cairo_font_options_get_antialias (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return CAIRO_ANTIALIAS_DEFAULT;
|
||||
|
||||
return options->antialias;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_subpixel_order:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @subpixel_order: the new subpixel order
|
||||
*
|
||||
* Sets the subpixel order for the font options object. The subpixel
|
||||
* order specifies the order of color elements within each pixel on
|
||||
* the display device when rendering with an antialiasing mode of
|
||||
* %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
|
||||
* #cairo_subpixel_order_t for full details.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
|
||||
cairo_subpixel_order_t subpixel_order)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
options->subpixel_order = subpixel_order;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_subpixel_order);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_subpixel_order:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the subpixel order for the font options object.
|
||||
* See the documentation for #cairo_subpixel_order_t for full details.
|
||||
*
|
||||
* Return value: the subpixel order for the font options object
|
||||
**/
|
||||
cairo_subpixel_order_t
|
||||
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
|
||||
return options->subpixel_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_hint_style:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @hint_style: the new hint style
|
||||
*
|
||||
* Sets the hint style for font outlines for the font options object.
|
||||
* This controls whether to fit font outlines to the pixel grid,
|
||||
* and if so, whether to optimize for fidelity or contrast.
|
||||
* See the documentation for #cairo_hint_style_t for full details.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_hint_style (cairo_font_options_t *options,
|
||||
cairo_hint_style_t hint_style)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
options->hint_style = hint_style;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_hint_style);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_hint_style:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the hint style for font outlines for the font options object.
|
||||
* See the documentation for #cairo_hint_style_t for full details.
|
||||
*
|
||||
* Return value: the hint style for the font options object
|
||||
**/
|
||||
cairo_hint_style_t
|
||||
cairo_font_options_get_hint_style (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return CAIRO_HINT_STYLE_DEFAULT;
|
||||
|
||||
return options->hint_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_hint_metrics:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @hint_metrics: the new metrics hinting mode
|
||||
*
|
||||
* Sets the metrics hinting mode for the font options object. This
|
||||
* controls whether metrics are quantized to integer values in
|
||||
* device units.
|
||||
* See the documentation for #cairo_hint_metrics_t for full details.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
|
||||
cairo_hint_metrics_t hint_metrics)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
options->hint_metrics = hint_metrics;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_hint_metrics);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_hint_metrics:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the metrics hinting mode for the font options object.
|
||||
* See the documentation for #cairo_hint_metrics_t for full details.
|
||||
*
|
||||
* Return value: the metrics hinting mode for the font options object
|
||||
**/
|
||||
cairo_hint_metrics_t
|
||||
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return CAIRO_HINT_METRICS_DEFAULT;
|
||||
|
||||
return options->hint_metrics;
|
||||
}
|
||||
71
uppdev/plugin/cairo/lib/cairo-freelist-private.h
Normal file
71
uppdev/plugin/cairo/lib/cairo-freelist-private.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright © 2006 Joonas Pihlaja
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef CAIRO_FREELIST_H
|
||||
#define CAIRO_FREELIST_H
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
/* Opaque implementation types. */
|
||||
typedef struct _cairo_freelist cairo_freelist_t;
|
||||
typedef struct _cairo_freelist_node cairo_freelist_node_t;
|
||||
|
||||
struct _cairo_freelist_node {
|
||||
cairo_freelist_node_t *next;
|
||||
};
|
||||
|
||||
struct _cairo_freelist {
|
||||
cairo_freelist_node_t *first_free_node;
|
||||
unsigned nodesize;
|
||||
};
|
||||
|
||||
|
||||
/* Initialise a freelist that will be responsible for allocating
|
||||
* nodes of size nodesize. */
|
||||
cairo_private void
|
||||
_cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize);
|
||||
|
||||
/* Deallocate any nodes in the freelist. */
|
||||
cairo_private void
|
||||
_cairo_freelist_fini (cairo_freelist_t *freelist);
|
||||
|
||||
/* Allocate a new node from the freelist. If the freelist contains no
|
||||
* nodes, a new one will be allocated using malloc(). The caller is
|
||||
* responsible for calling _cairo_freelist_free() or free() on the
|
||||
* returned node. Returns %NULL on memory allocation error. */
|
||||
cairo_private void *
|
||||
_cairo_freelist_alloc (cairo_freelist_t *freelist);
|
||||
|
||||
/* Allocate a new node from the freelist. If the freelist contains no
|
||||
* nodes, a new one will be allocated using calloc(). The caller is
|
||||
* responsible for calling _cairo_freelist_free() or free() on the
|
||||
* returned node. Returns %NULL on memory allocation error. */
|
||||
cairo_private void *
|
||||
_cairo_freelist_calloc (cairo_freelist_t *freelist);
|
||||
|
||||
/* Return a node to the freelist. This does not deallocate the memory,
|
||||
* but makes it available for later reuse by
|
||||
* _cairo_freelist_alloc(). */
|
||||
cairo_private void
|
||||
_cairo_freelist_free (cairo_freelist_t *freelist, void *node);
|
||||
|
||||
#endif /* CAIRO_FREELIST_H */
|
||||
73
uppdev/plugin/cairo/lib/cairo-freelist.c
Normal file
73
uppdev/plugin/cairo/lib/cairo-freelist.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright © 2006 Joonas Pihlaja
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-freelist-private.h"
|
||||
|
||||
void
|
||||
_cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize)
|
||||
{
|
||||
memset (freelist, 0, sizeof(cairo_freelist_t));
|
||||
freelist->nodesize = nodesize;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_freelist_fini (cairo_freelist_t *freelist)
|
||||
{
|
||||
cairo_freelist_node_t *node = freelist->first_free_node;
|
||||
while (node) {
|
||||
cairo_freelist_node_t *next = node->next;
|
||||
free (node);
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
_cairo_freelist_alloc (cairo_freelist_t *freelist)
|
||||
{
|
||||
if (freelist->first_free_node) {
|
||||
cairo_freelist_node_t *node = freelist->first_free_node;
|
||||
freelist->first_free_node = node->next;
|
||||
return (void*)node;
|
||||
}
|
||||
return malloc (freelist->nodesize);
|
||||
}
|
||||
|
||||
void *
|
||||
_cairo_freelist_calloc (cairo_freelist_t *freelist)
|
||||
{
|
||||
void *node = _cairo_freelist_alloc (freelist);
|
||||
if (node)
|
||||
memset (node, 0, freelist->nodesize);
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode)
|
||||
{
|
||||
cairo_freelist_node_t *node = voidnode;
|
||||
if (node) {
|
||||
node->next = freelist->first_free_node;
|
||||
freelist->first_free_node = node;
|
||||
}
|
||||
}
|
||||
2746
uppdev/plugin/cairo/lib/cairo-ft-font.c
Normal file
2746
uppdev/plugin/cairo/lib/cairo-ft-font.c
Normal file
File diff suppressed because it is too large
Load diff
70
uppdev/plugin/cairo/lib/cairo-ft-private.h
Normal file
70
uppdev/plugin/cairo/lib/cairo-ft-private.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_FT_PRIVATE_H
|
||||
#define CAIRO_FT_PRIVATE_H
|
||||
|
||||
#include "cairo-ft.h"
|
||||
#include "cairoint.h"
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
typedef struct _cairo_ft_unscaled_font cairo_ft_unscaled_font_t;
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
/* These functions are needed by the PDF backend, which needs to keep track of the
|
||||
* the different fonts-on-disk used by a document, so it can embed them
|
||||
*/
|
||||
cairo_private cairo_unscaled_font_t *
|
||||
_cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_private FT_Face
|
||||
_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled);
|
||||
|
||||
cairo_private void
|
||||
_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_HAS_FT_FONT */
|
||||
#endif /* CAIRO_FT_PRIVATE_H */
|
||||
75
uppdev/plugin/cairo/lib/cairo-ft.h
Normal file
75
uppdev/plugin/cairo/lib/cairo-ft.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_FT_H
|
||||
#define CAIRO_FT_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
|
||||
/* Fontconfig/Freetype platform-specific font interface */
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
|
||||
|
||||
cairo_public void
|
||||
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern);
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_ft_font_face_create_for_ft_face (FT_Face face,
|
||||
int load_flags);
|
||||
|
||||
cairo_public FT_Face
|
||||
cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_public void
|
||||
cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_FT_FONT */
|
||||
# error Cairo was not compiled with support for the freetype font backend
|
||||
#endif /* CAIRO_HAS_FT_FONT */
|
||||
|
||||
#endif /* CAIRO_FT_H */
|
||||
41
uppdev/plugin/cairo/lib/cairo-glitz-private.h
Normal file
41
uppdev/plugin/cairo/lib/cairo-glitz-private.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_GLITZ_PRIVATE_H
|
||||
#define CAIRO_GLITZ_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-glitz.h"
|
||||
|
||||
slim_hidden_proto (cairo_glitz_surface_create);
|
||||
|
||||
#endif /* CAIRO_GLITZ_PRIVATE_H */
|
||||
2495
uppdev/plugin/cairo/lib/cairo-glitz-surface.c
Normal file
2495
uppdev/plugin/cairo/lib/cairo-glitz-surface.c
Normal file
File diff suppressed because it is too large
Load diff
57
uppdev/plugin/cairo/lib/cairo-glitz.h
Normal file
57
uppdev/plugin/cairo/lib/cairo-glitz.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_GLITZ_H
|
||||
#define CAIRO_GLITZ_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_GLITZ_SURFACE
|
||||
|
||||
#include <glitz.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_glitz_surface_create (glitz_surface_t *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_GLITZ_SURFACE */
|
||||
# error Cairo was not compiled with support for the glitz backend
|
||||
#endif /* CAIRO_HAS_GLITZ_SURFACE */
|
||||
|
||||
#endif /* CAIRO_GLITZ_H */
|
||||
71
uppdev/plugin/cairo/lib/cairo-gstate-private.h
Normal file
71
uppdev/plugin/cairo/lib/cairo-gstate-private.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_GSTATE_PRIVATE_H
|
||||
#define CAIRO_GSTATE_PRIVATE_H
|
||||
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
struct _cairo_gstate {
|
||||
cairo_operator_t op;
|
||||
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
|
||||
cairo_stroke_style_t stroke_style;
|
||||
|
||||
cairo_fill_rule_t fill_rule;
|
||||
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_scaled_font_t *scaled_font; /* Specific to the current CTM */
|
||||
cairo_matrix_t font_matrix;
|
||||
cairo_font_options_t font_options;
|
||||
|
||||
cairo_clip_t clip;
|
||||
|
||||
cairo_surface_t *target; /* The target to which all rendering is directed */
|
||||
cairo_surface_t *parent_target; /* The previous target which was receiving rendering */
|
||||
cairo_surface_t *original_target; /* The original target the initial gstate was created with */
|
||||
|
||||
cairo_matrix_t ctm;
|
||||
cairo_matrix_t ctm_inverse;
|
||||
cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */
|
||||
|
||||
cairo_pattern_t *source;
|
||||
|
||||
struct _cairo_gstate *next;
|
||||
};
|
||||
|
||||
#endif /* CAIRO_GSTATE_PRIVATE_H */
|
||||
1858
uppdev/plugin/cairo/lib/cairo-gstate.c
Normal file
1858
uppdev/plugin/cairo/lib/cairo-gstate.c
Normal file
File diff suppressed because it is too large
Load diff
88
uppdev/plugin/cairo/lib/cairo-hash-private.h
Normal file
88
uppdev/plugin/cairo/lib/cairo-hash-private.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc.
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_HASH_PRIVATE_H
|
||||
#define CAIRO_HASH_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
/* XXX: I'd like this file to be self-contained in terms of
|
||||
* includeability, but that's not really possible with the current
|
||||
* monolithic cairoint.h. So, for now, just include cairoint.h instead
|
||||
* if you want to include this file. */
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_hash_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_hash_predicate_func_t) (void *entry);
|
||||
|
||||
typedef void
|
||||
(*cairo_hash_callback_func_t) (void *entry,
|
||||
void *closure);
|
||||
|
||||
cairo_private cairo_hash_table_t *
|
||||
_cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal);
|
||||
|
||||
cairo_private void
|
||||
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key,
|
||||
cairo_hash_entry_t **entry_return);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_predicate_func_t predicate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_hash_table_insert (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *entry);
|
||||
|
||||
cairo_private void
|
||||
_cairo_hash_table_remove (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key);
|
||||
|
||||
cairo_private void
|
||||
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_callback_func_t hash_callback,
|
||||
void *closure);
|
||||
|
||||
#endif
|
||||
576
uppdev/plugin/cairo/lib/cairo-hash.c
Normal file
576
uppdev/plugin/cairo/lib/cairo-hash.c
Normal file
|
|
@ -0,0 +1,576 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc.
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/*
|
||||
* An entry can be in one of three states:
|
||||
*
|
||||
* FREE: Entry has never been used, terminates all searches.
|
||||
* Appears in the table as a %NULL pointer.
|
||||
*
|
||||
* DEAD: Entry had been live in the past. A dead entry can be reused
|
||||
* but does not terminate a search for an exact entry.
|
||||
* Appears in the table as a pointer to DEAD_ENTRY.
|
||||
*
|
||||
* LIVE: Entry is currently being used.
|
||||
* Appears in the table as any non-%NULL, non-DEAD_ENTRY pointer.
|
||||
*/
|
||||
|
||||
static cairo_hash_entry_t dead_entry = { 0 };
|
||||
#define DEAD_ENTRY (&dead_entry)
|
||||
|
||||
#define ENTRY_IS_FREE(entry) ((entry) == NULL)
|
||||
#define ENTRY_IS_DEAD(entry) ((entry) == DEAD_ENTRY)
|
||||
#define ENTRY_IS_LIVE(entry) ((entry) && ! ENTRY_IS_DEAD(entry))
|
||||
|
||||
/* We expect keys will not be destroyed frequently, so our table does not
|
||||
* contain any explicit shrinking code nor any chain-coalescing code for
|
||||
* entries randomly deleted by memory pressure (except during rehashing, of
|
||||
* course). These assumptions are potentially bad, but they make the
|
||||
* implementation straightforward.
|
||||
*
|
||||
* Revisit later if evidence appears that we're using excessive memory from
|
||||
* a mostly-dead table.
|
||||
*
|
||||
* This table is open-addressed with double hashing. Each table size is a
|
||||
* prime chosen to be a little more than double the high water mark for a
|
||||
* given arrangement, so the tables should remain < 50% full. The table
|
||||
* size makes for the "first" hash modulus; a second prime (2 less than the
|
||||
* first prime) serves as the "second" hash modulus, which is co-prime and
|
||||
* thus guarantees a complete permutation of table indices.
|
||||
*
|
||||
* This structure, and accompanying table, is borrowed/modified from the
|
||||
* file xserver/render/glyph.c in the freedesktop.org x server, with
|
||||
* permission (and suggested modification of doubling sizes) by Keith
|
||||
* Packard.
|
||||
*/
|
||||
|
||||
typedef struct _cairo_hash_table_arrangement {
|
||||
unsigned long high_water_mark;
|
||||
unsigned long size;
|
||||
unsigned long rehash;
|
||||
} cairo_hash_table_arrangement_t;
|
||||
|
||||
static const cairo_hash_table_arrangement_t hash_table_arrangements [] = {
|
||||
{ 16, 43, 41 },
|
||||
{ 32, 73, 71 },
|
||||
{ 64, 151, 149 },
|
||||
{ 128, 283, 281 },
|
||||
{ 256, 571, 569 },
|
||||
{ 512, 1153, 1151 },
|
||||
{ 1024, 2269, 2267 },
|
||||
{ 2048, 4519, 4517 },
|
||||
{ 4096, 9013, 9011 },
|
||||
{ 8192, 18043, 18041 },
|
||||
{ 16384, 36109, 36107 },
|
||||
{ 32768, 72091, 72089 },
|
||||
{ 65536, 144409, 144407 },
|
||||
{ 131072, 288361, 288359 },
|
||||
{ 262144, 576883, 576881 },
|
||||
{ 524288, 1153459, 1153457 },
|
||||
{ 1048576, 2307163, 2307161 },
|
||||
{ 2097152, 4613893, 4613891 },
|
||||
{ 4194304, 9227641, 9227639 },
|
||||
{ 8388608, 18455029, 18455027 },
|
||||
{ 16777216, 36911011, 36911009 },
|
||||
{ 33554432, 73819861, 73819859 },
|
||||
{ 67108864, 147639589, 147639587 },
|
||||
{ 134217728, 295279081, 295279079 },
|
||||
{ 268435456, 590559793, 590559791 }
|
||||
};
|
||||
|
||||
#define NUM_HASH_TABLE_ARRANGEMENTS ARRAY_LENGTH (hash_table_arrangements)
|
||||
|
||||
struct _cairo_hash_table {
|
||||
cairo_hash_keys_equal_func_t keys_equal;
|
||||
|
||||
const cairo_hash_table_arrangement_t *arrangement;
|
||||
cairo_hash_entry_t **entries;
|
||||
|
||||
unsigned long live_entries;
|
||||
unsigned long iterating; /* Iterating, no insert, no resize */
|
||||
};
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_create:
|
||||
* @keys_equal: a function to return %TRUE if two keys are equal
|
||||
*
|
||||
* Creates a new hash table which will use the keys_equal() function
|
||||
* to compare hash keys. Data is provided to the hash table in the
|
||||
* form of user-derived versions of #cairo_hash_entry_t. A hash entry
|
||||
* must be able to hold both a key (including a hash code) and a
|
||||
* value. Sometimes only the key will be necessary, (as in
|
||||
* _cairo_hash_table_remove), and other times both a key and a value
|
||||
* will be necessary, (as in _cairo_hash_table_insert).
|
||||
*
|
||||
* See #cairo_hash_entry_t for more details.
|
||||
*
|
||||
* Return value: the new hash table or %NULL if out of memory.
|
||||
**/
|
||||
cairo_hash_table_t *
|
||||
_cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
|
||||
{
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
hash_table = malloc (sizeof (cairo_hash_table_t));
|
||||
if (hash_table == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_table->keys_equal = keys_equal;
|
||||
|
||||
hash_table->arrangement = &hash_table_arrangements[0];
|
||||
|
||||
hash_table->entries = calloc (hash_table->arrangement->size,
|
||||
sizeof(cairo_hash_entry_t *));
|
||||
if (hash_table->entries == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
free (hash_table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_table->live_entries = 0;
|
||||
hash_table->iterating = 0;
|
||||
|
||||
return hash_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_destroy:
|
||||
* @hash_table: an empty hash table to destroy
|
||||
*
|
||||
* Immediately destroys the given hash table, freeing all resources
|
||||
* associated with it.
|
||||
*
|
||||
* WARNING: The hash_table must have no live entries in it before
|
||||
* _cairo_hash_table_destroy is called. It is a fatal error otherwise,
|
||||
* and this function will halt. The rationale for this behavior is to
|
||||
* avoid memory leaks and to avoid needless complication of the API
|
||||
* with destroy notifiy callbacks.
|
||||
*
|
||||
* WARNING: The hash_table must have no running iterators in it when
|
||||
* _cairo_hash_table_destroy is called. It is a fatal error otherwise,
|
||||
* and this function will halt.
|
||||
**/
|
||||
void
|
||||
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table)
|
||||
{
|
||||
if (hash_table == NULL)
|
||||
return;
|
||||
|
||||
/* The hash table must be empty. Otherwise, halt. */
|
||||
assert (hash_table->live_entries == 0);
|
||||
/* No iterators can be running. Otherwise, halt. */
|
||||
assert (hash_table->iterating == 0);
|
||||
|
||||
free (hash_table->entries);
|
||||
hash_table->entries = NULL;
|
||||
|
||||
free (hash_table);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_lookup_internal:
|
||||
*
|
||||
* @hash_table: a #cairo_hash_table_t to search
|
||||
* @key: the key to search on
|
||||
* @hash_code: the hash_code for @key
|
||||
* @key_unique: If %TRUE, then caller asserts that no key already
|
||||
* exists that will compare equal to #key, so search can be
|
||||
* optimized. If unsure, set to %FALSE and the code will always work.
|
||||
*
|
||||
* Search the hashtable for a live entry for which
|
||||
* hash_table->keys_equal returns true. If no such entry exists then
|
||||
* return the first available (free or dead entry).
|
||||
*
|
||||
* If the key_unique flag is set, then the search will never call
|
||||
* hash_table->keys_equal and will act as if it always returned
|
||||
* false. This is useful as a performance optimization in special
|
||||
* circumstances where the caller knows that there is no existing
|
||||
* entry in the hash table with a matching key.
|
||||
*
|
||||
* Return value: The matching entry in the hash table (if
|
||||
* any). Otherwise, the first available entry. The caller should check
|
||||
* entry->state to check whether a match was found or not.
|
||||
**/
|
||||
static cairo_hash_entry_t **
|
||||
_cairo_hash_table_lookup_internal (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key,
|
||||
cairo_bool_t key_is_unique)
|
||||
{
|
||||
cairo_hash_entry_t **entry, **first_available = NULL;
|
||||
unsigned long table_size, i, idx, step;
|
||||
|
||||
table_size = hash_table->arrangement->size;
|
||||
|
||||
idx = key->hash % table_size;
|
||||
step = 0;
|
||||
|
||||
for (i = 0; i < table_size; ++i)
|
||||
{
|
||||
entry = &hash_table->entries[idx];
|
||||
|
||||
if (ENTRY_IS_FREE(*entry))
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
else if (ENTRY_IS_DEAD(*entry))
|
||||
{
|
||||
if (key_is_unique) {
|
||||
return entry;
|
||||
} else {
|
||||
if (! first_available)
|
||||
first_available = entry;
|
||||
}
|
||||
}
|
||||
else /* ENTRY_IS_LIVE(*entry) */
|
||||
{
|
||||
if (! key_is_unique)
|
||||
if (hash_table->keys_equal (key, *entry))
|
||||
return entry;
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
step = key->hash % hash_table->arrangement->rehash;
|
||||
if (step == 0)
|
||||
step = 1;
|
||||
}
|
||||
|
||||
idx += step;
|
||||
if (idx >= table_size)
|
||||
idx -= table_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* The table should not have permitted you to get here if you were just
|
||||
* looking for a free slot: there should have been room.
|
||||
*/
|
||||
assert (key_is_unique == 0);
|
||||
|
||||
return first_available;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_resize:
|
||||
* @hash_table: a hash table
|
||||
*
|
||||
* Resize the hash table if the number of entries has gotten much
|
||||
* bigger or smaller than the ideal number of entries for the current
|
||||
* size.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if out of memory.
|
||||
**/
|
||||
static cairo_status_t
|
||||
_cairo_hash_table_resize (cairo_hash_table_t *hash_table)
|
||||
{
|
||||
cairo_hash_table_t tmp;
|
||||
cairo_hash_entry_t **entry;
|
||||
unsigned long new_size, i;
|
||||
|
||||
/* This keeps the hash table between 25% and 50% full. */
|
||||
unsigned long high = hash_table->arrangement->high_water_mark;
|
||||
unsigned long low = high >> 2;
|
||||
|
||||
if (hash_table->live_entries >= low && hash_table->live_entries <= high)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
tmp = *hash_table;
|
||||
|
||||
if (hash_table->live_entries > high)
|
||||
{
|
||||
tmp.arrangement = hash_table->arrangement + 1;
|
||||
/* This code is being abused if we can't make a table big enough. */
|
||||
assert (tmp.arrangement - hash_table_arrangements <
|
||||
NUM_HASH_TABLE_ARRANGEMENTS);
|
||||
}
|
||||
else /* hash_table->live_entries < low */
|
||||
{
|
||||
/* Can't shrink if we're at the smallest size */
|
||||
if (hash_table->arrangement == &hash_table_arrangements[0])
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
tmp.arrangement = hash_table->arrangement - 1;
|
||||
}
|
||||
|
||||
new_size = tmp.arrangement->size;
|
||||
tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*));
|
||||
if (tmp.entries == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
for (i = 0; i < hash_table->arrangement->size; ++i) {
|
||||
if (ENTRY_IS_LIVE (hash_table->entries[i])) {
|
||||
entry = _cairo_hash_table_lookup_internal (&tmp,
|
||||
hash_table->entries[i],
|
||||
TRUE);
|
||||
assert (ENTRY_IS_FREE(*entry));
|
||||
*entry = hash_table->entries[i];
|
||||
}
|
||||
}
|
||||
|
||||
free (hash_table->entries);
|
||||
hash_table->entries = tmp.entries;
|
||||
hash_table->arrangement = tmp.arrangement;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_lookup:
|
||||
* @hash_table: a hash table
|
||||
* @key: the key of interest
|
||||
* @entry_return: pointer for return value.
|
||||
*
|
||||
* Performs a lookup in @hash_table looking for an entry which has a
|
||||
* key that matches @key, (as determined by the keys_equal() function
|
||||
* passed to _cairo_hash_table_create).
|
||||
*
|
||||
* Return value: %TRUE if there is an entry in the hash table that
|
||||
* matches the given key, (which will now be in *entry_return). %FALSE
|
||||
* otherwise, (in which case *entry_return will be %NULL).
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key,
|
||||
cairo_hash_entry_t **entry_return)
|
||||
{
|
||||
cairo_hash_entry_t **entry;
|
||||
|
||||
/* See if we have an entry in the table already. */
|
||||
entry = _cairo_hash_table_lookup_internal (hash_table, key, FALSE);
|
||||
if (ENTRY_IS_LIVE(*entry)) {
|
||||
*entry_return = *entry;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*entry_return = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_random_entry:
|
||||
* @hash_table: a hash table
|
||||
* @predicate: a predicate function, or %NULL for any entry.
|
||||
*
|
||||
* Find a random entry in the hash table satisfying the given
|
||||
* @predicate. A %NULL @predicate is taken as equivalent to a function
|
||||
* which always returns %TRUE, (eg. any entry in the table will do).
|
||||
*
|
||||
* We use the same algorithm as the lookup algorithm to walk over the
|
||||
* entries in the hash table in a pseudo-random order. Walking
|
||||
* linearly would favor entries following gaps in the hash table. We
|
||||
* could also call rand() repeatedly, which works well for almost-full
|
||||
* tables, but degrades when the table is almost empty, or predicate
|
||||
* returns %TRUE for most entries.
|
||||
*
|
||||
* Return value: a random live entry or %NULL if there are no entries
|
||||
* that match the given predicate. In particular, if predicate is
|
||||
* %NULL, a %NULL return value indicates that the table is empty.
|
||||
**/
|
||||
void *
|
||||
_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_predicate_func_t predicate)
|
||||
{
|
||||
cairo_hash_entry_t **entry;
|
||||
unsigned long hash;
|
||||
unsigned long table_size, i, idx, step;
|
||||
|
||||
table_size = hash_table->arrangement->size;
|
||||
|
||||
hash = rand ();
|
||||
idx = hash % table_size;
|
||||
step = 0;
|
||||
|
||||
for (i = 0; i < table_size; ++i)
|
||||
{
|
||||
entry = &hash_table->entries[idx];
|
||||
|
||||
if (ENTRY_IS_LIVE (*entry) &&
|
||||
(predicate == NULL || predicate (*entry)))
|
||||
{
|
||||
return *entry;
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
step = hash % hash_table->arrangement->rehash;
|
||||
if (step == 0)
|
||||
step = 1;
|
||||
}
|
||||
|
||||
idx += step;
|
||||
if (idx >= table_size)
|
||||
idx -= table_size;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_insert:
|
||||
* @hash_table: a hash table
|
||||
* @key_and_value: an entry to be inserted
|
||||
*
|
||||
* Insert the entry #key_and_value into the hash table.
|
||||
*
|
||||
* WARNING: It is a fatal error if an entry exists in the hash table
|
||||
* with a matching key, (this function will halt).
|
||||
*
|
||||
* WARNING: It is a fatal error to insert an element while
|
||||
* an iterator is running
|
||||
*
|
||||
* Instead of using insert to replace an entry, consider just editing
|
||||
* the entry obtained with _cairo_hash_table_lookup. Or if absolutely
|
||||
* necessary, use _cairo_hash_table_remove first.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_hash_table_insert (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key_and_value)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_hash_entry_t **entry;
|
||||
|
||||
/* Insert is illegal while an iterator is running. */
|
||||
assert (hash_table->iterating == 0);
|
||||
|
||||
entry = _cairo_hash_table_lookup_internal (hash_table,
|
||||
key_and_value, FALSE);
|
||||
|
||||
if (ENTRY_IS_LIVE(*entry))
|
||||
{
|
||||
/* User is being bad, let's crash. */
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
*entry = key_and_value;
|
||||
hash_table->live_entries++;
|
||||
|
||||
status = _cairo_hash_table_resize (hash_table);
|
||||
if (status) {
|
||||
/* abort the insert... */
|
||||
*entry = DEAD_ENTRY;
|
||||
hash_table->live_entries--;
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_remove:
|
||||
* @hash_table: a hash table
|
||||
* @key: key of entry to be removed
|
||||
*
|
||||
* Remove an entry from the hash table which has a key that matches
|
||||
* @key, if any (as determined by the keys_equal() function passed to
|
||||
* _cairo_hash_table_create).
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if successful or
|
||||
* %CAIRO_STATUS_NO_MEMORY if out of memory.
|
||||
**/
|
||||
void
|
||||
_cairo_hash_table_remove (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key)
|
||||
{
|
||||
cairo_hash_entry_t **entry;
|
||||
|
||||
entry = _cairo_hash_table_lookup_internal (hash_table, key, FALSE);
|
||||
if (! ENTRY_IS_LIVE(*entry))
|
||||
return;
|
||||
|
||||
*entry = DEAD_ENTRY;
|
||||
hash_table->live_entries--;
|
||||
|
||||
/* Check for table resize. Don't do this when iterating as this will
|
||||
* reorder elements of the table and cause the iteration to potentially
|
||||
* skip some elements. */
|
||||
if (hash_table->iterating == 0) {
|
||||
/* This call _can_ fail, but only in failing to allocate new
|
||||
* memory to shrink the hash table. It does leave the table in a
|
||||
* consistent state, and we've already succeeded in removing the
|
||||
* entry, so we don't examine the failure status of this call. */
|
||||
_cairo_hash_table_resize (hash_table);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_hash_table_foreach:
|
||||
* @hash_table: a hash table
|
||||
* @hash_callback: function to be called for each live entry
|
||||
* @closure: additional argument to be passed to @hash_callback
|
||||
*
|
||||
* Call @hash_callback for each live entry in the hash table, in a
|
||||
* non-specified order.
|
||||
*
|
||||
* Entries in @hash_table may be removed by code executed from @hash_callback.
|
||||
*
|
||||
* Entries may not be inserted to @hash_table, nor may @hash_table
|
||||
* be destroyed by code executed from @hash_callback. The relevant
|
||||
* functions will halt in these cases.
|
||||
**/
|
||||
void
|
||||
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_callback_func_t hash_callback,
|
||||
void *closure)
|
||||
{
|
||||
unsigned long i;
|
||||
cairo_hash_entry_t *entry;
|
||||
|
||||
if (hash_table == NULL)
|
||||
return;
|
||||
|
||||
/* Mark the table for iteration */
|
||||
++hash_table->iterating;
|
||||
for (i = 0; i < hash_table->arrangement->size; i++) {
|
||||
entry = hash_table->entries[i];
|
||||
if (ENTRY_IS_LIVE(entry))
|
||||
hash_callback (entry, closure);
|
||||
}
|
||||
/* If some elements were deleted during the iteration,
|
||||
* the table may need resizing. Just do this every time
|
||||
* as the check is inexpensive.
|
||||
*/
|
||||
if (--hash_table->iterating == 0) {
|
||||
/* Should we fail to shrink the hash table, it is left unaltered,
|
||||
* and we don't need to propagate the error status. */
|
||||
_cairo_hash_table_resize (hash_table);
|
||||
}
|
||||
}
|
||||
222
uppdev/plugin/cairo/lib/cairo-hull.c
Normal file
222
uppdev/plugin/cairo/lib/cairo-hull.c
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct cairo_hull {
|
||||
cairo_point_t point;
|
||||
cairo_slope_t slope;
|
||||
int discard;
|
||||
int id;
|
||||
} cairo_hull_t;
|
||||
|
||||
static void
|
||||
_cairo_hull_init (cairo_hull_t *hull,
|
||||
cairo_pen_vertex_t *vertices,
|
||||
int num_vertices)
|
||||
{
|
||||
cairo_point_t *p, *extremum, tmp;
|
||||
int i;
|
||||
|
||||
extremum = &vertices[0].point;
|
||||
for (i = 1; i < num_vertices; i++) {
|
||||
p = &vertices[i].point;
|
||||
if (p->y < extremum->y || (p->y == extremum->y && p->x < extremum->x))
|
||||
extremum = p;
|
||||
}
|
||||
/* Put the extremal point at the beginning of the array */
|
||||
tmp = *extremum;
|
||||
*extremum = vertices[0].point;
|
||||
vertices[0].point = tmp;
|
||||
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
hull[i].point = vertices[i].point;
|
||||
_cairo_slope_init (&hull[i].slope, &hull[0].point, &hull[i].point);
|
||||
|
||||
/* give each point a unique id for later comparison */
|
||||
hull[i].id = i;
|
||||
|
||||
/* Don't discard by default */
|
||||
hull[i].discard = 0;
|
||||
|
||||
/* Discard all points coincident with the extremal point */
|
||||
if (i != 0 && hull[i].slope.dx == 0 && hull[i].slope.dy == 0)
|
||||
hull[i].discard = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline cairo_int64_t
|
||||
_slope_length (cairo_slope_t *slope)
|
||||
{
|
||||
return _cairo_int64_add (_cairo_int32x32_64_mul (slope->dx, slope->dx),
|
||||
_cairo_int32x32_64_mul (slope->dy, slope->dy));
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_hull_vertex_compare (const void *av, const void *bv)
|
||||
{
|
||||
cairo_hull_t *a = (cairo_hull_t *) av;
|
||||
cairo_hull_t *b = (cairo_hull_t *) bv;
|
||||
int ret;
|
||||
|
||||
ret = _cairo_slope_compare (&a->slope, &b->slope);
|
||||
|
||||
/*
|
||||
* In the case of two vertices with identical slope from the
|
||||
* extremal point discard the nearer point.
|
||||
*/
|
||||
if (ret == 0) {
|
||||
int cmp;
|
||||
|
||||
cmp = _cairo_int64_cmp (_slope_length (&a->slope),
|
||||
_slope_length (&b->slope));
|
||||
|
||||
/*
|
||||
* Use the points' ids to ensure a well-defined ordering,
|
||||
* and avoid setting discard on both points.
|
||||
*/
|
||||
if (cmp < 0 || (cmp == 0 && a->id < b->id)) {
|
||||
a->discard = 1;
|
||||
ret = -1;
|
||||
} else {
|
||||
b->discard = 1;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_hull_prev_valid (cairo_hull_t *hull, int num_hull, int index)
|
||||
{
|
||||
/* hull[0] is always valid, and we never need to wraparound, (if
|
||||
* we are passed an index of 0 here, then the calling loop is just
|
||||
* about to terminate). */
|
||||
if (index == 0)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
index--;
|
||||
} while (hull[index].discard);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_hull_next_valid (cairo_hull_t *hull, int num_hull, int index)
|
||||
{
|
||||
do {
|
||||
index = (index + 1) % num_hull;
|
||||
} while (hull[index].discard);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_hull_eliminate_concave (cairo_hull_t *hull, int num_hull)
|
||||
{
|
||||
int i, j, k;
|
||||
cairo_slope_t slope_ij, slope_jk;
|
||||
|
||||
i = 0;
|
||||
j = _cairo_hull_next_valid (hull, num_hull, i);
|
||||
k = _cairo_hull_next_valid (hull, num_hull, j);
|
||||
|
||||
do {
|
||||
_cairo_slope_init (&slope_ij, &hull[i].point, &hull[j].point);
|
||||
_cairo_slope_init (&slope_jk, &hull[j].point, &hull[k].point);
|
||||
|
||||
/* Is the angle formed by ij and jk concave? */
|
||||
if (_cairo_slope_compare (&slope_ij, &slope_jk) >= 0) {
|
||||
if (i == k)
|
||||
return;
|
||||
hull[j].discard = 1;
|
||||
j = i;
|
||||
i = _cairo_hull_prev_valid (hull, num_hull, j);
|
||||
} else {
|
||||
i = j;
|
||||
j = k;
|
||||
k = _cairo_hull_next_valid (hull, num_hull, j);
|
||||
}
|
||||
} while (j != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_hull_to_pen (cairo_hull_t *hull, cairo_pen_vertex_t *vertices, int *num_vertices)
|
||||
{
|
||||
int i, j = 0;
|
||||
|
||||
for (i = 0; i < *num_vertices; i++) {
|
||||
if (hull[i].discard)
|
||||
continue;
|
||||
vertices[j++].point = hull[i].point;
|
||||
}
|
||||
|
||||
*num_vertices = j;
|
||||
}
|
||||
|
||||
/* Given a set of vertices, compute the convex hull using the Graham
|
||||
scan algorithm. */
|
||||
cairo_status_t
|
||||
_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices)
|
||||
{
|
||||
cairo_hull_t hull_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_hull_t)];
|
||||
cairo_hull_t *hull;
|
||||
int num_hull = *num_vertices;
|
||||
|
||||
if (num_hull > ARRAY_LENGTH (hull_stack)) {
|
||||
hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t));
|
||||
if (hull == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
hull = hull_stack;
|
||||
}
|
||||
|
||||
_cairo_hull_init (hull, vertices, num_hull);
|
||||
|
||||
qsort (hull + 1, num_hull - 1,
|
||||
sizeof (cairo_hull_t), _cairo_hull_vertex_compare);
|
||||
|
||||
_cairo_hull_eliminate_concave (hull, num_hull);
|
||||
|
||||
_cairo_hull_to_pen (hull, vertices, num_vertices);
|
||||
|
||||
if (hull != hull_stack)
|
||||
free (hull);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
1388
uppdev/plugin/cairo/lib/cairo-image-surface.c
Normal file
1388
uppdev/plugin/cairo/lib/cairo-image-surface.c
Normal file
File diff suppressed because it is too large
Load diff
403
uppdev/plugin/cairo/lib/cairo-lzw.c
Normal file
403
uppdev/plugin/cairo/lib/cairo-lzw.c
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _lzw_buf {
|
||||
cairo_status_t status;
|
||||
|
||||
unsigned char *data;
|
||||
int data_size;
|
||||
int num_data;
|
||||
uint32_t pending;
|
||||
unsigned int pending_bits;
|
||||
} lzw_buf_t;
|
||||
|
||||
/* An lzw_buf_t is a simple, growable chunk of memory for holding
|
||||
* variable-size objects of up to 16 bits each.
|
||||
*
|
||||
* Initialize an lzw_buf_t to the given size in bytes.
|
||||
*
|
||||
* To store objects into the lzw_buf_t, call _lzw_buf_store_bits and
|
||||
* when finished, call _lzw_buf_store_pending, (which flushes out the
|
||||
* last few bits that hadn't yet made a complete byte yet).
|
||||
*
|
||||
* Instead of returning failure from any functions, lzw_buf_t provides
|
||||
* a status value that the caller can query, (and should query at
|
||||
* least once when done with the object). The status value will be
|
||||
* either %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY;
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_init (lzw_buf_t *buf, int size)
|
||||
{
|
||||
if (size == 0)
|
||||
size = 16;
|
||||
|
||||
buf->status = CAIRO_STATUS_SUCCESS;
|
||||
buf->data_size = size;
|
||||
buf->num_data = 0;
|
||||
buf->pending = 0;
|
||||
buf->pending_bits = 0;
|
||||
|
||||
buf->data = malloc (size);
|
||||
if (buf->data == NULL) {
|
||||
buf->data_size = 0;
|
||||
buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increase the buffer size by doubling.
|
||||
*
|
||||
* Returns %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*/
|
||||
static cairo_status_t
|
||||
_lzw_buf_grow (lzw_buf_t *buf)
|
||||
{
|
||||
int new_size = buf->data_size * 2;
|
||||
unsigned char *new_data;
|
||||
|
||||
if (buf->status)
|
||||
return buf->status;
|
||||
|
||||
new_data = NULL;
|
||||
/* check for integer overflow */
|
||||
if (new_size / 2 == buf->data_size)
|
||||
new_data = realloc (buf->data, new_size);
|
||||
|
||||
if (new_data == NULL) {
|
||||
free (buf->data);
|
||||
buf->data_size = 0;
|
||||
buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return buf->status;
|
||||
}
|
||||
|
||||
buf->data = new_data;
|
||||
buf->data_size = new_size;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Store the lowest num_bits bits of values into buf.
|
||||
*
|
||||
* Note: The bits of value above size_in_bits must be 0, (so don't lie
|
||||
* about the size).
|
||||
*
|
||||
* See also _lzw_buf_store_pending which must be called after the last
|
||||
* call to _lzw_buf_store_bits.
|
||||
*
|
||||
* Sets buf->status to either %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY.
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_store_bits (lzw_buf_t *buf, uint16_t value, int num_bits)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (value <= (1 << num_bits) - 1);
|
||||
|
||||
if (buf->status)
|
||||
return;
|
||||
|
||||
buf->pending = (buf->pending << num_bits) | value;
|
||||
buf->pending_bits += num_bits;
|
||||
|
||||
while (buf->pending_bits >= 8) {
|
||||
if (buf->num_data >= buf->data_size) {
|
||||
status = _lzw_buf_grow (buf);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
buf->data[buf->num_data++] = buf->pending >> (buf->pending_bits - 8);
|
||||
buf->pending_bits -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the last remaining pending bits into the buffer.
|
||||
*
|
||||
* Note: This function must be called after the last call to
|
||||
* _lzw_buf_store_bits.
|
||||
*
|
||||
* Sets buf->status to either %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY.
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_store_pending (lzw_buf_t *buf)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (buf->status)
|
||||
return;
|
||||
|
||||
if (buf->pending_bits == 0)
|
||||
return;
|
||||
|
||||
assert (buf->pending_bits < 8);
|
||||
|
||||
if (buf->num_data >= buf->data_size) {
|
||||
status = _lzw_buf_grow (buf);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
|
||||
buf->data[buf->num_data++] = buf->pending << (8 - buf->pending_bits);
|
||||
buf->pending_bits = 0;
|
||||
}
|
||||
|
||||
/* LZW defines a few magic code values */
|
||||
#define LZW_CODE_CLEAR_TABLE 256
|
||||
#define LZW_CODE_EOD 257
|
||||
#define LZW_CODE_FIRST 258
|
||||
|
||||
/* We pack three separate values into a symbol as follows:
|
||||
*
|
||||
* 12 bits (31 down to 20): CODE: code value used to represent this symbol
|
||||
* 12 bits (19 down to 8): PREV: previous code value in chain
|
||||
* 8 bits ( 7 down to 0): NEXT: next byte value in chain
|
||||
*/
|
||||
typedef uint32_t lzw_symbol_t;
|
||||
|
||||
#define LZW_SYMBOL_SET(sym, prev, next) ((sym) = ((prev) << 8)|(next))
|
||||
#define LZW_SYMBOL_SET_CODE(sym, code, prev, next) ((sym) = ((code << 20)|(prev) << 8)|(next))
|
||||
#define LZW_SYMBOL_GET_CODE(sym) (((sym) >> 20))
|
||||
#define LZW_SYMBOL_GET_PREV(sym) (((sym) >> 8) & 0x7ff)
|
||||
#define LZW_SYMBOL_GET_BYTE(sym) (((sym) >> 0) & 0x0ff)
|
||||
|
||||
/* The PREV+NEXT fields can be seen as the key used to fetch values
|
||||
* from the hash table, while the code is the value fetched.
|
||||
*/
|
||||
#define LZW_SYMBOL_KEY_MASK 0x000fffff
|
||||
|
||||
/* Since code values are only stored starting with 258 we can safely
|
||||
* use a zero value to represent free slots in the hash table. */
|
||||
#define LZW_SYMBOL_FREE 0x00000000
|
||||
|
||||
/* These really aren't very free for modifying. First, the PostScript
|
||||
* specification sets the 9-12 bit range. Second, the encoding of
|
||||
* lzw_symbol_t above also relies on 2 of LZW_BITS_MAX plus one byte
|
||||
* fitting within 32 bits.
|
||||
*
|
||||
* But other than that, the LZW compression scheme could function with
|
||||
* more bits per code.
|
||||
*/
|
||||
#define LZW_BITS_MIN 9
|
||||
#define LZW_BITS_MAX 12
|
||||
#define LZW_BITS_BOUNDARY(bits) ((1<<(bits))-1)
|
||||
#define LZW_MAX_SYMBOLS (1<<LZW_BITS_MAX)
|
||||
|
||||
#define LZW_SYMBOL_TABLE_SIZE 9013
|
||||
#define LZW_SYMBOL_MOD1 LZW_SYMBOL_TABLE_SIZE
|
||||
#define LZW_SYMBOL_MOD2 9011
|
||||
|
||||
typedef struct _lzw_symbol_table {
|
||||
lzw_symbol_t table[LZW_SYMBOL_TABLE_SIZE];
|
||||
} lzw_symbol_table_t;
|
||||
|
||||
/* Initialize the hash table to entirely empty */
|
||||
static void
|
||||
_lzw_symbol_table_init (lzw_symbol_table_t *table)
|
||||
{
|
||||
memset (table->table, 0, LZW_SYMBOL_TABLE_SIZE * sizeof (lzw_symbol_t));
|
||||
}
|
||||
|
||||
/* Lookup a symbol in the symbol table. The PREV and NEXT fields of
|
||||
* symbol form the key for the lookup.
|
||||
*
|
||||
* If successful, then this function returns %TRUE and slot_ret will be
|
||||
* left pointing at the result that will have the CODE field of
|
||||
* interest.
|
||||
*
|
||||
* If the lookup fails, then this function returns %FALSE and slot_ret
|
||||
* will be pointing at the location in the table to which a new CODE
|
||||
* value should be stored along with PREV and NEXT.
|
||||
*/
|
||||
static cairo_bool_t
|
||||
_lzw_symbol_table_lookup (lzw_symbol_table_t *table,
|
||||
lzw_symbol_t symbol,
|
||||
lzw_symbol_t **slot_ret)
|
||||
{
|
||||
/* The algorithm here is identical to that in cairo-hash.c. We
|
||||
* copy it here to allow for a rather more efficient
|
||||
* implementation due to several circumstances that do not apply
|
||||
* to the more general case:
|
||||
*
|
||||
* 1) We have a known bound on the total number of symbols, so we
|
||||
* have a fixed-size table without any copying when growing
|
||||
*
|
||||
* 2) We never delete any entries, so we don't need to
|
||||
* support/check for DEAD entries during lookup.
|
||||
*
|
||||
* 3) The object fits in 32 bits so we store each object in its
|
||||
* entirety within the table rather than storing objects
|
||||
* externally and putting pointers in the table, (which here
|
||||
* would just double the storage requirements and have negative
|
||||
* impacts on memory locality).
|
||||
*/
|
||||
int i, idx, step, hash = symbol & LZW_SYMBOL_KEY_MASK;
|
||||
lzw_symbol_t candidate;
|
||||
|
||||
idx = hash % LZW_SYMBOL_MOD1;
|
||||
step = 0;
|
||||
|
||||
*slot_ret = NULL;
|
||||
for (i = 0; i < LZW_SYMBOL_TABLE_SIZE; i++)
|
||||
{
|
||||
candidate = table->table[idx];
|
||||
if (candidate == LZW_SYMBOL_FREE)
|
||||
{
|
||||
*slot_ret = &table->table[idx];
|
||||
return FALSE;
|
||||
}
|
||||
else /* candidate is LIVE */
|
||||
{
|
||||
if ((candidate & LZW_SYMBOL_KEY_MASK) ==
|
||||
(symbol & LZW_SYMBOL_KEY_MASK))
|
||||
{
|
||||
*slot_ret = &table->table[idx];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
step = hash % LZW_SYMBOL_MOD2;
|
||||
if (step == 0)
|
||||
step = 1;
|
||||
}
|
||||
|
||||
idx += step;
|
||||
if (idx >= LZW_SYMBOL_TABLE_SIZE)
|
||||
idx -= LZW_SYMBOL_TABLE_SIZE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Compress a bytestream using the LZW algorithm.
|
||||
*
|
||||
* This is an original implementation based on reading the
|
||||
* specification of the LZWDecode filter in the PostScript Language
|
||||
* Reference. The free parameters in the LZW algorithm are set to the
|
||||
* values mandated by PostScript, (symbols encoded with widths from 9
|
||||
* to 12 bits).
|
||||
*
|
||||
* This function returns a pointer to a newly allocated buffer holding
|
||||
* the compressed data, or %NULL if an out-of-memory situation
|
||||
* occurs.
|
||||
*
|
||||
* Notice that any one of the _lzw_buf functions called here could
|
||||
* trigger an out-of-memory condition. But lzw_buf_t uses cairo's
|
||||
* shutdown-on-error idiom, so it's safe to continue to call into
|
||||
* lzw_buf without having to check for errors, (until a final check at
|
||||
* the end).
|
||||
*/
|
||||
unsigned char *
|
||||
_cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out)
|
||||
{
|
||||
int bytes_remaining = *size_in_out;
|
||||
lzw_buf_t buf;
|
||||
lzw_symbol_table_t table;
|
||||
lzw_symbol_t symbol, *slot = NULL; /* just to squelch a warning */
|
||||
int code_next = LZW_CODE_FIRST;
|
||||
int code_bits = LZW_BITS_MIN;
|
||||
int prev, next = 0; /* just to squelch a warning */
|
||||
|
||||
if (*size_in_out == 0)
|
||||
return NULL;
|
||||
|
||||
_lzw_buf_init (&buf, *size_in_out);
|
||||
|
||||
_lzw_symbol_table_init (&table);
|
||||
|
||||
/* The LZW header is a clear table code. */
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_CLEAR_TABLE, code_bits);
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Find the longest existing code in the symbol table that
|
||||
* matches the current input, if any. */
|
||||
prev = *data++;
|
||||
bytes_remaining--;
|
||||
if (bytes_remaining) {
|
||||
do
|
||||
{
|
||||
next = *data++;
|
||||
bytes_remaining--;
|
||||
LZW_SYMBOL_SET (symbol, prev, next);
|
||||
if (_lzw_symbol_table_lookup (&table, symbol, &slot))
|
||||
prev = LZW_SYMBOL_GET_CODE (*slot);
|
||||
} while (bytes_remaining && *slot != LZW_SYMBOL_FREE);
|
||||
if (*slot == LZW_SYMBOL_FREE) {
|
||||
data--;
|
||||
bytes_remaining++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the code into the output. This is either a byte read
|
||||
* directly from the input, or a code from the last successful
|
||||
* lookup. */
|
||||
_lzw_buf_store_bits (&buf, prev, code_bits);
|
||||
|
||||
if (bytes_remaining == 0)
|
||||
break;
|
||||
|
||||
LZW_SYMBOL_SET_CODE (*slot, code_next++, prev, next);
|
||||
|
||||
if (code_next > LZW_BITS_BOUNDARY(code_bits))
|
||||
{
|
||||
code_bits++;
|
||||
if (code_bits > LZW_BITS_MAX) {
|
||||
_lzw_symbol_table_init (&table);
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_CLEAR_TABLE, code_bits - 1);
|
||||
code_bits = LZW_BITS_MIN;
|
||||
code_next = LZW_CODE_FIRST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The LZW footer is an end-of-data code. */
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_EOD, code_bits);
|
||||
|
||||
_lzw_buf_store_pending (&buf);
|
||||
|
||||
/* See if we ever ran out of memory while writing to buf. */
|
||||
if (buf.status == CAIRO_STATUS_NO_MEMORY) {
|
||||
*size_in_out = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (buf.status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
*size_in_out = buf.num_data;
|
||||
return buf.data;
|
||||
}
|
||||
141
uppdev/plugin/cairo/lib/cairo-malloc-private.h
Normal file
141
uppdev/plugin/cairo/lib/cairo-malloc-private.h
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_MALLOC_PRIVATE_H
|
||||
#define CAIRO_MALLOC_PRIVATE_H
|
||||
|
||||
#include "cairo-wideint-private.h"
|
||||
|
||||
/**
|
||||
* _cairo_malloc:
|
||||
* @size: size in bytes
|
||||
*
|
||||
* Allocate @size memory using malloc().
|
||||
* The memory should be freed using free().
|
||||
* malloc is skipped, if 0 bytes are requested, and %NULL will be returned.
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of malloc() failure or size is 0.
|
||||
*/
|
||||
|
||||
#define _cairo_malloc(size) \
|
||||
((size) ? malloc((unsigned) (size)) : NULL)
|
||||
|
||||
/**
|
||||
* _cairo_malloc_ab:
|
||||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Allocates @n*@size memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the multiplication. Behaves much like
|
||||
* calloc(), except that the returned memory is not set to zero.
|
||||
* The memory should be freed using free().
|
||||
*
|
||||
* @size should be a constant so that the compiler can optimize
|
||||
* out a constant division.
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of malloc() failure or overflow.
|
||||
*/
|
||||
|
||||
#define _cairo_malloc_ab(a, size) \
|
||||
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
_cairo_malloc((unsigned) (a) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_realloc_ab:
|
||||
* @ptr: original pointer to block of memory to be resized
|
||||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Reallocates @ptr a block of @n*@size memory using realloc(), taking
|
||||
* care to not overflow when doing the multiplication. The memory
|
||||
* should be freed using free().
|
||||
*
|
||||
* @size should be a constant so that the compiler can optimize
|
||||
* out a constant division.
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of realloc() failure or overflow (whereupon the original block
|
||||
* of memory * is left untouched).
|
||||
*/
|
||||
|
||||
#define _cairo_realloc_ab(ptr, a, size) \
|
||||
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
realloc(ptr, (unsigned) (a) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_malloc_abc:
|
||||
* @n: first factor of number of elements to allocate
|
||||
* @b: second factor of number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Allocates @n*@b*@size memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the multiplication. Behaves like
|
||||
* _cairo_malloc_ab(). The memory should be freed using free().
|
||||
*
|
||||
* @size should be a constant so that the compiler can optimize
|
||||
* out a constant division.
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of malloc() failure or overflow.
|
||||
*/
|
||||
|
||||
#define _cairo_malloc_abc(a, b, size) \
|
||||
((b) && (unsigned) (a) >= INT32_MAX / (unsigned) (b) ? NULL : \
|
||||
(size) && (unsigned) ((a)*(b)) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
_cairo_malloc((unsigned) (a) * (unsigned) (b) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_malloc_ab_plus_c:
|
||||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
* @k: additional size to allocate
|
||||
*
|
||||
* Allocates @n*@ksize+@k memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the arithmetic. Behaves like
|
||||
* _cairo_malloc_ab(). The memory should be freed using free().
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of malloc() failure or overflow.
|
||||
*/
|
||||
|
||||
#define _cairo_malloc_ab_plus_c(n, size, k) \
|
||||
((size) && (unsigned) (n) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
(unsigned) (k) >= INT32_MAX - (unsigned) (n) * (unsigned) (size) ? NULL : \
|
||||
_cairo_malloc((unsigned) (n) * (unsigned) (size) + (unsigned) (k)))
|
||||
|
||||
#endif /* CAIRO_MALLOC_PRIVATE_H */
|
||||
863
uppdev/plugin/cairo/lib/cairo-matrix.c
Normal file
863
uppdev/plugin/cairo/lib/cairo-matrix.c
Normal file
|
|
@ -0,0 +1,863 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
|
||||
#define ISFINITE(x) isfinite (x)
|
||||
#else
|
||||
#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
|
||||
#endif
|
||||
|
||||
static void
|
||||
_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar);
|
||||
|
||||
static void
|
||||
_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix);
|
||||
|
||||
/**
|
||||
* cairo_matrix_init_identity:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
*
|
||||
* Modifies @matrix to be an identity transformation.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_init_identity (cairo_matrix_t *matrix)
|
||||
{
|
||||
cairo_matrix_init (matrix,
|
||||
1, 0,
|
||||
0, 1,
|
||||
0, 0);
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_init_identity);
|
||||
|
||||
/**
|
||||
* cairo_matrix_init:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @xx: xx component of the affine transformation
|
||||
* @yx: yx component of the affine transformation
|
||||
* @xy: xy component of the affine transformation
|
||||
* @yy: yy component of the affine transformation
|
||||
* @x0: X translation component of the affine transformation
|
||||
* @y0: Y translation component of the affine transformation
|
||||
*
|
||||
* Sets @matrix to be the affine transformation given by
|
||||
* @xx, @yx, @xy, @yy, @x0, @y0. The transformation is given
|
||||
* by:
|
||||
* <programlisting>
|
||||
* x_new = xx * x + xy * y + x0;
|
||||
* y_new = yx * x + yy * y + y0;
|
||||
* </programlisting>
|
||||
**/
|
||||
void
|
||||
cairo_matrix_init (cairo_matrix_t *matrix,
|
||||
double xx, double yx,
|
||||
|
||||
double xy, double yy,
|
||||
double x0, double y0)
|
||||
{
|
||||
matrix->xx = xx; matrix->yx = yx;
|
||||
matrix->xy = xy; matrix->yy = yy;
|
||||
matrix->x0 = x0; matrix->y0 = y0;
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_init);
|
||||
|
||||
/**
|
||||
* _cairo_matrix_get_affine:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @xx: location to store xx component of matrix
|
||||
* @yx: location to store yx component of matrix
|
||||
* @xy: location to store xy component of matrix
|
||||
* @yy: location to store yy component of matrix
|
||||
* @x0: location to store x0 (X-translation component) of matrix, or %NULL
|
||||
* @y0: location to store y0 (Y-translation component) of matrix, or %NULL
|
||||
*
|
||||
* Gets the matrix values for the affine transformation that @matrix represents.
|
||||
* See cairo_matrix_init().
|
||||
*
|
||||
*
|
||||
* This function is a leftover from the old public API, but is still
|
||||
* mildly useful as an internal means for getting at the matrix
|
||||
* members in a positional way. For example, when reassigning to some
|
||||
* external matrix type, or when renaming members to more meaningful
|
||||
* names (such as a,b,c,d,e,f) for particular manipulations.
|
||||
**/
|
||||
void
|
||||
_cairo_matrix_get_affine (const cairo_matrix_t *matrix,
|
||||
double *xx, double *yx,
|
||||
double *xy, double *yy,
|
||||
double *x0, double *y0)
|
||||
{
|
||||
*xx = matrix->xx;
|
||||
*yx = matrix->yx;
|
||||
|
||||
*xy = matrix->xy;
|
||||
*yy = matrix->yy;
|
||||
|
||||
if (x0)
|
||||
*x0 = matrix->x0;
|
||||
if (y0)
|
||||
*y0 = matrix->y0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_matrix_init_translate:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @tx: amount to translate in the X direction
|
||||
* @ty: amount to translate in the Y direction
|
||||
*
|
||||
* Initializes @matrix to a transformation that translates by @tx and
|
||||
* @ty in the X and Y dimensions, respectively.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_init_translate (cairo_matrix_t *matrix,
|
||||
double tx, double ty)
|
||||
{
|
||||
cairo_matrix_init (matrix,
|
||||
1, 0,
|
||||
0, 1,
|
||||
tx, ty);
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_init_translate);
|
||||
|
||||
/**
|
||||
* cairo_matrix_translate:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @tx: amount to translate in the X direction
|
||||
* @ty: amount to translate in the Y direction
|
||||
*
|
||||
* Applies a translation by @tx, @ty to the transformation in
|
||||
* @matrix. The effect of the new transformation is to first translate
|
||||
* the coordinates by @tx and @ty, then apply the original transformation
|
||||
* to the coordinates.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_translate (cairo_matrix_t *matrix, double tx, double ty)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
cairo_matrix_init_translate (&tmp, tx, ty);
|
||||
|
||||
cairo_matrix_multiply (matrix, &tmp, matrix);
|
||||
}
|
||||
slim_hidden_def (cairo_matrix_translate);
|
||||
|
||||
/**
|
||||
* cairo_matrix_init_scale:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @sx: scale factor in the X direction
|
||||
* @sy: scale factor in the Y direction
|
||||
*
|
||||
* Initializes @matrix to a transformation that scales by @sx and @sy
|
||||
* in the X and Y dimensions, respectively.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_init_scale (cairo_matrix_t *matrix,
|
||||
double sx, double sy)
|
||||
{
|
||||
cairo_matrix_init (matrix,
|
||||
sx, 0,
|
||||
0, sy,
|
||||
0, 0);
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_init_scale);
|
||||
|
||||
/**
|
||||
* cairo_matrix_scale:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @sx: scale factor in the X direction
|
||||
* @sy: scale factor in the Y direction
|
||||
*
|
||||
* Applies scaling by @sx, @sy to the transformation in @matrix. The
|
||||
* effect of the new transformation is to first scale the coordinates
|
||||
* by @sx and @sy, then apply the original transformation to the coordinates.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
cairo_matrix_init_scale (&tmp, sx, sy);
|
||||
|
||||
cairo_matrix_multiply (matrix, &tmp, matrix);
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_scale);
|
||||
|
||||
/**
|
||||
* cairo_matrix_init_rotate:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @radians: angle of rotation, in radians. The direction of rotation
|
||||
* is defined such that positive angles rotate in the direction from
|
||||
* the positive X axis toward the positive Y axis. With the default
|
||||
* axis orientation of cairo, positive angles rotate in a clockwise
|
||||
* direction.
|
||||
*
|
||||
* Initialized @matrix to a transformation that rotates by @radians.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_init_rotate (cairo_matrix_t *matrix,
|
||||
double radians)
|
||||
{
|
||||
double s;
|
||||
double c;
|
||||
|
||||
s = sin (radians);
|
||||
c = cos (radians);
|
||||
|
||||
cairo_matrix_init (matrix,
|
||||
c, s,
|
||||
-s, c,
|
||||
0, 0);
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_init_rotate);
|
||||
|
||||
/**
|
||||
* cairo_matrix_rotate:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @radians: angle of rotation, in radians. The direction of rotation
|
||||
* is defined such that positive angles rotate in the direction from
|
||||
* the positive X axis toward the positive Y axis. With the default
|
||||
* axis orientation of cairo, positive angles rotate in a clockwise
|
||||
* direction.
|
||||
*
|
||||
* Applies rotation by @radians to the transformation in
|
||||
* @matrix. The effect of the new transformation is to first rotate the
|
||||
* coordinates by @radians, then apply the original transformation
|
||||
* to the coordinates.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_rotate (cairo_matrix_t *matrix, double radians)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
cairo_matrix_init_rotate (&tmp, radians);
|
||||
|
||||
cairo_matrix_multiply (matrix, &tmp, matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_matrix_multiply:
|
||||
* @result: a #cairo_matrix_t in which to store the result
|
||||
* @a: a #cairo_matrix_t
|
||||
* @b: a #cairo_matrix_t
|
||||
*
|
||||
* Multiplies the affine transformations in @a and @b together
|
||||
* and stores the result in @result. The effect of the resulting
|
||||
* transformation is to first apply the transformation in @a to the
|
||||
* coordinates and then apply the transformation in @b to the
|
||||
* coordinates.
|
||||
*
|
||||
* It is allowable for @result to be identical to either @a or @b.
|
||||
**/
|
||||
/*
|
||||
* XXX: The ordering of the arguments to this function corresponds
|
||||
* to [row_vector]*A*B. If we want to use column vectors instead,
|
||||
* then we need to switch the two arguments and fix up all
|
||||
* uses.
|
||||
*/
|
||||
void
|
||||
cairo_matrix_multiply (cairo_matrix_t *result, const cairo_matrix_t *a, const cairo_matrix_t *b)
|
||||
{
|
||||
cairo_matrix_t r;
|
||||
|
||||
r.xx = a->xx * b->xx + a->yx * b->xy;
|
||||
r.yx = a->xx * b->yx + a->yx * b->yy;
|
||||
|
||||
r.xy = a->xy * b->xx + a->yy * b->xy;
|
||||
r.yy = a->xy * b->yx + a->yy * b->yy;
|
||||
|
||||
r.x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0;
|
||||
r.y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0;
|
||||
|
||||
*result = r;
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_multiply);
|
||||
|
||||
/**
|
||||
* cairo_matrix_transform_distance:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @dx: X component of a distance vector. An in/out parameter
|
||||
* @dy: Y component of a distance vector. An in/out parameter
|
||||
*
|
||||
* Transforms the distance vector (@dx,@dy) by @matrix. This is
|
||||
* similar to cairo_matrix_transform_point() except that the translation
|
||||
* components of the transformation are ignored. The calculation of
|
||||
* the returned vector is as follows:
|
||||
*
|
||||
* <programlisting>
|
||||
* dx2 = dx1 * a + dy1 * c;
|
||||
* dy2 = dx1 * b + dy1 * d;
|
||||
* </programlisting>
|
||||
*
|
||||
* Affine transformations are position invariant, so the same vector
|
||||
* always transforms to the same vector. If (@x1,@y1) transforms
|
||||
* to (@x2,@y2) then (@x1+@dx1,@y1+@dy1) will transform to
|
||||
* (@x1+@dx2,@y1+@dy2) for all values of @x1 and @x2.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_transform_distance (const cairo_matrix_t *matrix, double *dx, double *dy)
|
||||
{
|
||||
double new_x, new_y;
|
||||
|
||||
new_x = (matrix->xx * *dx + matrix->xy * *dy);
|
||||
new_y = (matrix->yx * *dx + matrix->yy * *dy);
|
||||
|
||||
*dx = new_x;
|
||||
*dy = new_y;
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_transform_distance);
|
||||
|
||||
/**
|
||||
* cairo_matrix_transform_point:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
* @x: X position. An in/out parameter
|
||||
* @y: Y position. An in/out parameter
|
||||
*
|
||||
* Transforms the point (@x, @y) by @matrix.
|
||||
**/
|
||||
void
|
||||
cairo_matrix_transform_point (const cairo_matrix_t *matrix, double *x, double *y)
|
||||
{
|
||||
cairo_matrix_transform_distance (matrix, x, y);
|
||||
|
||||
*x += matrix->x0;
|
||||
*y += matrix->y0;
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_transform_point);
|
||||
|
||||
void
|
||||
_cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2,
|
||||
cairo_bool_t *is_tight)
|
||||
{
|
||||
int i;
|
||||
double quad_x[4], quad_y[4];
|
||||
double min_x, max_x;
|
||||
double min_y, max_y;
|
||||
|
||||
quad_x[0] = *x1;
|
||||
quad_y[0] = *y1;
|
||||
cairo_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]);
|
||||
|
||||
quad_x[1] = *x2;
|
||||
quad_y[1] = *y1;
|
||||
cairo_matrix_transform_point (matrix, &quad_x[1], &quad_y[1]);
|
||||
|
||||
quad_x[2] = *x1;
|
||||
quad_y[2] = *y2;
|
||||
cairo_matrix_transform_point (matrix, &quad_x[2], &quad_y[2]);
|
||||
|
||||
quad_x[3] = *x2;
|
||||
quad_y[3] = *y2;
|
||||
cairo_matrix_transform_point (matrix, &quad_x[3], &quad_y[3]);
|
||||
|
||||
min_x = max_x = quad_x[0];
|
||||
min_y = max_y = quad_y[0];
|
||||
|
||||
for (i=1; i < 4; i++) {
|
||||
if (quad_x[i] < min_x)
|
||||
min_x = quad_x[i];
|
||||
if (quad_x[i] > max_x)
|
||||
max_x = quad_x[i];
|
||||
|
||||
if (quad_y[i] < min_y)
|
||||
min_y = quad_y[i];
|
||||
if (quad_y[i] > max_y)
|
||||
max_y = quad_y[i];
|
||||
}
|
||||
|
||||
*x1 = min_x;
|
||||
*y1 = min_y;
|
||||
*x2 = max_x;
|
||||
*y2 = max_y;
|
||||
|
||||
if (is_tight) {
|
||||
/* it's tight if and only if the four corner points form an axis-aligned
|
||||
rectangle.
|
||||
And that's true if and only if we can derive corners 0 and 3 from
|
||||
corners 1 and 2 in one of two straightforward ways...
|
||||
We could use a tolerance here but for now we'll fall back to FALSE in the case
|
||||
of floating point error.
|
||||
*/
|
||||
*is_tight =
|
||||
(quad_x[1] == quad_x[0] && quad_y[1] == quad_y[3] &&
|
||||
quad_x[2] == quad_x[3] && quad_y[2] == quad_y[0]) ||
|
||||
(quad_x[1] == quad_x[3] && quad_y[1] == quad_y[0] &&
|
||||
quad_x[2] == quad_x[0] && quad_y[2] == quad_y[3]);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_private void
|
||||
_cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix,
|
||||
cairo_box_t *bbox,
|
||||
cairo_bool_t *is_tight)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
_cairo_box_to_doubles (bbox, &x1, &y1, &x2, &y2);
|
||||
_cairo_matrix_transform_bounding_box (matrix, &x1, &y1, &x2, &y2, is_tight);
|
||||
_cairo_box_from_doubles (bbox, &x1, &y1, &x2, &y2);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar)
|
||||
{
|
||||
matrix->xx *= scalar;
|
||||
matrix->yx *= scalar;
|
||||
|
||||
matrix->xy *= scalar;
|
||||
matrix->yy *= scalar;
|
||||
|
||||
matrix->x0 *= scalar;
|
||||
matrix->y0 *= scalar;
|
||||
}
|
||||
|
||||
/* This function isn't a correct adjoint in that the implicit 1 in the
|
||||
homogeneous result should actually be ad-bc instead. But, since this
|
||||
adjoint is only used in the computation of the inverse, which
|
||||
divides by det (A)=ad-bc anyway, everything works out in the end. */
|
||||
static void
|
||||
_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix)
|
||||
{
|
||||
/* adj (A) = transpose (C:cofactor (A,i,j)) */
|
||||
double a, b, c, d, tx, ty;
|
||||
|
||||
_cairo_matrix_get_affine (matrix,
|
||||
&a, &b,
|
||||
&c, &d,
|
||||
&tx, &ty);
|
||||
|
||||
cairo_matrix_init (matrix,
|
||||
d, -b,
|
||||
-c, a,
|
||||
c*ty - d*tx, b*tx - a*ty);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_matrix_invert:
|
||||
* @matrix: a #cairo_matrix_t
|
||||
*
|
||||
* Changes @matrix to be the inverse of it's original value. Not
|
||||
* all transformation matrices have inverses; if the matrix
|
||||
* collapses points together (it is <firstterm>degenerate</firstterm>),
|
||||
* then it has no inverse and this function will fail.
|
||||
*
|
||||
* Returns: If @matrix has an inverse, modifies @matrix to
|
||||
* be the inverse matrix and returns %CAIRO_STATUS_SUCCESS. Otherwise,
|
||||
* returns %CAIRO_STATUS_INVALID_MATRIX.
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_matrix_invert (cairo_matrix_t *matrix)
|
||||
{
|
||||
/* inv (A) = 1/det (A) * adj (A) */
|
||||
double det;
|
||||
|
||||
det = _cairo_matrix_compute_determinant (matrix);
|
||||
|
||||
if (! ISFINITE (det))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
if (det == 0)
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
_cairo_matrix_compute_adjoint (matrix);
|
||||
_cairo_matrix_scalar_multiply (matrix, 1 / det);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_invert);
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
|
||||
{
|
||||
double det;
|
||||
|
||||
det = _cairo_matrix_compute_determinant (matrix);
|
||||
|
||||
return ISFINITE (det) && det != 0.;
|
||||
}
|
||||
|
||||
double
|
||||
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix)
|
||||
{
|
||||
double a, b, c, d;
|
||||
|
||||
a = matrix->xx; b = matrix->yx;
|
||||
c = matrix->xy; d = matrix->yy;
|
||||
|
||||
return a*d - b*c;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_matrix_compute_basis_scale_factors:
|
||||
* @matrix: a matrix
|
||||
* @basis_scale: the scale factor in the direction of basis
|
||||
* @normal_scale: the scale factor in the direction normal to the basis
|
||||
* @x_basis: basis to use. X basis if true, Y basis otherwise.
|
||||
*
|
||||
* Computes |Mv| and det(M)/|Mv| for v=[1,0] if x_basis is true, and v=[0,1]
|
||||
* otherwise, and M is @matrix.
|
||||
*
|
||||
* Return value: the scale factor of @matrix on the height of the font,
|
||||
* or 1.0 if @matrix is %NULL.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
|
||||
double *basis_scale, double *normal_scale,
|
||||
cairo_bool_t x_basis)
|
||||
{
|
||||
double det;
|
||||
|
||||
det = _cairo_matrix_compute_determinant (matrix);
|
||||
|
||||
if (! ISFINITE (det))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
if (det == 0)
|
||||
{
|
||||
*basis_scale = *normal_scale = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double x = x_basis != 0;
|
||||
double y = x == 0;
|
||||
double major, minor;
|
||||
|
||||
cairo_matrix_transform_distance (matrix, &x, &y);
|
||||
major = sqrt(x*x + y*y);
|
||||
/*
|
||||
* ignore mirroring
|
||||
*/
|
||||
if (det < 0)
|
||||
det = -det;
|
||||
if (major)
|
||||
minor = det / major;
|
||||
else
|
||||
minor = 0.0;
|
||||
if (x_basis)
|
||||
{
|
||||
*basis_scale = major;
|
||||
*normal_scale = minor;
|
||||
}
|
||||
else
|
||||
{
|
||||
*basis_scale = minor;
|
||||
*normal_scale = major;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_matrix_is_identity (const cairo_matrix_t *matrix)
|
||||
{
|
||||
return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
|
||||
matrix->xy == 0.0 && matrix->yy == 1.0 &&
|
||||
matrix->x0 == 0.0 && matrix->y0 == 0.0);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_matrix_is_translation (const cairo_matrix_t *matrix)
|
||||
{
|
||||
return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
|
||||
matrix->xy == 0.0 && matrix->yy == 1.0);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_matrix_is_integer_translation (const cairo_matrix_t *matrix,
|
||||
int *itx, int *ity)
|
||||
{
|
||||
if (_cairo_matrix_is_translation (matrix))
|
||||
{
|
||||
cairo_fixed_t x0_fixed = _cairo_fixed_from_double (matrix->x0);
|
||||
cairo_fixed_t y0_fixed = _cairo_fixed_from_double (matrix->y0);
|
||||
|
||||
if (_cairo_fixed_is_integer (x0_fixed) &&
|
||||
_cairo_fixed_is_integer (y0_fixed))
|
||||
{
|
||||
if (itx)
|
||||
*itx = _cairo_fixed_integer_part (x0_fixed);
|
||||
if (ity)
|
||||
*ity = _cairo_fixed_integer_part (y0_fixed);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* By pixel exact here, we mean a matrix that is composed only of
|
||||
* 90 degree rotations, flips, and integer translations and produces a 1:1
|
||||
* mapping between source and destination pixels. If we transform an image
|
||||
* with a pixel-exact matrix, filtering is not useful.
|
||||
*/
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix)
|
||||
{
|
||||
cairo_fixed_t x0_fixed, y0_fixed;
|
||||
|
||||
if (matrix->xy == 0.0 && matrix->yx == 0.0) {
|
||||
if (! (matrix->xx == 1.0 || matrix->xx == -1.0))
|
||||
return FALSE;
|
||||
if (! (matrix->yy == 1.0 || matrix->yy == -1.0))
|
||||
return FALSE;
|
||||
} else if (matrix->xx == 0.0 && matrix->yy == 0.0) {
|
||||
if (! (matrix->xy == 1.0 || matrix->xy == -1.0))
|
||||
return FALSE;
|
||||
if (! (matrix->yx == 1.0 || matrix->yx == -1.0))
|
||||
return FALSE;
|
||||
} else
|
||||
return FALSE;
|
||||
|
||||
x0_fixed = _cairo_fixed_from_double (matrix->x0);
|
||||
y0_fixed = _cairo_fixed_from_double (matrix->y0);
|
||||
|
||||
return _cairo_fixed_is_integer (x0_fixed) && _cairo_fixed_is_integer (y0_fixed);
|
||||
}
|
||||
|
||||
/*
|
||||
A circle in user space is transformed into an ellipse in device space.
|
||||
|
||||
The following is a derivation of a formula to calculate the length of the
|
||||
major axis for this ellipse; this is useful for error bounds calculations.
|
||||
|
||||
Thanks to Walter Brisken <wbrisken@aoc.nrao.edu> for this derivation:
|
||||
|
||||
1. First some notation:
|
||||
|
||||
All capital letters represent vectors in two dimensions. A prime '
|
||||
represents a transformed coordinate. Matrices are written in underlined
|
||||
form, ie _R_. Lowercase letters represent scalar real values.
|
||||
|
||||
2. The question has been posed: What is the maximum expansion factor
|
||||
achieved by the linear transformation
|
||||
|
||||
X' = X _R_
|
||||
|
||||
where _R_ is a real-valued 2x2 matrix with entries:
|
||||
|
||||
_R_ = [a b]
|
||||
[c d] .
|
||||
|
||||
In other words, what is the maximum radius, MAX[ |X'| ], reached for any
|
||||
X on the unit circle ( |X| = 1 ) ?
|
||||
|
||||
3. Some useful formulae
|
||||
|
||||
(A) through (C) below are standard double-angle formulae. (D) is a lesser
|
||||
known result and is derived below:
|
||||
|
||||
(A) sin²(θ) = (1 - cos(2*θ))/2
|
||||
(B) cos²(θ) = (1 + cos(2*θ))/2
|
||||
(C) sin(θ)*cos(θ) = sin(2*θ)/2
|
||||
(D) MAX[a*cos(θ) + b*sin(θ)] = sqrt(a² + b²)
|
||||
|
||||
Proof of (D):
|
||||
|
||||
find the maximum of the function by setting the derivative to zero:
|
||||
|
||||
-a*sin(θ)+b*cos(θ) = 0
|
||||
|
||||
From this it follows that
|
||||
|
||||
tan(θ) = b/a
|
||||
|
||||
and hence
|
||||
|
||||
sin(θ) = b/sqrt(a² + b²)
|
||||
|
||||
and
|
||||
|
||||
cos(θ) = a/sqrt(a² + b²)
|
||||
|
||||
Thus the maximum value is
|
||||
|
||||
MAX[a*cos(θ) + b*sin(θ)] = (a² + b²)/sqrt(a² + b²)
|
||||
= sqrt(a² + b²)
|
||||
|
||||
4. Derivation of maximum expansion
|
||||
|
||||
To find MAX[ |X'| ] we search brute force method using calculus. The unit
|
||||
circle on which X is constrained is to be parameterized by t:
|
||||
|
||||
X(θ) = (cos(θ), sin(θ))
|
||||
|
||||
Thus
|
||||
|
||||
X'(θ) = X(θ) * _R_ = (cos(θ), sin(θ)) * [a b]
|
||||
[c d]
|
||||
= (a*cos(θ) + c*sin(θ), b*cos(θ) + d*sin(θ)).
|
||||
|
||||
Define
|
||||
|
||||
r(θ) = |X'(θ)|
|
||||
|
||||
Thus
|
||||
|
||||
r²(θ) = (a*cos(θ) + c*sin(θ))² + (b*cos(θ) + d*sin(θ))²
|
||||
= (a² + b²)*cos²(θ) + (c² + d²)*sin²(θ)
|
||||
+ 2*(a*c + b*d)*cos(θ)*sin(θ)
|
||||
|
||||
Now apply the double angle formulae (A) to (C) from above:
|
||||
|
||||
r²(θ) = (a² + b² + c² + d²)/2
|
||||
+ (a² + b² - c² - d²)*cos(2*θ)/2
|
||||
+ (a*c + b*d)*sin(2*θ)
|
||||
= f + g*cos(φ) + h*sin(φ)
|
||||
|
||||
Where
|
||||
|
||||
f = (a² + b² + c² + d²)/2
|
||||
g = (a² + b² - c² - d²)/2
|
||||
h = (a*c + d*d)
|
||||
φ = 2*θ
|
||||
|
||||
It is clear that MAX[ |X'| ] = sqrt(MAX[ r² ]). Here we determine MAX[ r² ]
|
||||
using (D) from above:
|
||||
|
||||
MAX[ r² ] = f + sqrt(g² + h²)
|
||||
|
||||
And finally
|
||||
|
||||
MAX[ |X'| ] = sqrt( f + sqrt(g² + h²) )
|
||||
|
||||
Which is the solution to this problem.
|
||||
|
||||
Walter Brisken
|
||||
2004/10/08
|
||||
|
||||
(Note that the minor axis length is at the minimum of the above solution,
|
||||
which is just sqrt ( f - sqrt(g² + h²) ) given the symmetry of (D)).
|
||||
|
||||
|
||||
For another derivation of the same result, using Singular Value Decomposition,
|
||||
see doc/tutorial/src/singular.c.
|
||||
*/
|
||||
|
||||
/* determine the length of the major axis of a circle of the given radius
|
||||
after applying the transformation matrix. */
|
||||
double
|
||||
_cairo_matrix_transformed_circle_major_axis (cairo_matrix_t *matrix, double radius)
|
||||
{
|
||||
double a, b, c, d, f, g, h, i, j;
|
||||
|
||||
_cairo_matrix_get_affine (matrix,
|
||||
&a, &b,
|
||||
&c, &d,
|
||||
NULL, NULL);
|
||||
|
||||
i = a*a + b*b;
|
||||
j = c*c + d*d;
|
||||
|
||||
f = 0.5 * (i + j);
|
||||
g = 0.5 * (i - j);
|
||||
h = a*c + b*d;
|
||||
|
||||
return radius * sqrt (f + sqrt (g*g+h*h));
|
||||
|
||||
/*
|
||||
* we don't need the minor axis length, which is
|
||||
* double min = radius * sqrt (f - sqrt (g*g+h*h));
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
|
||||
pixman_transform_t *pixman_transform)
|
||||
{
|
||||
static const pixman_transform_t pixman_identity_transform = {{
|
||||
{1 << 16, 0, 0},
|
||||
{ 0, 1 << 16, 0},
|
||||
{ 0, 0, 1 << 16}
|
||||
}};
|
||||
|
||||
if (_cairo_matrix_is_identity (matrix)) {
|
||||
*pixman_transform = pixman_identity_transform;
|
||||
}
|
||||
else {
|
||||
cairo_matrix_t inv = *matrix;
|
||||
double x = 0, y = 0;
|
||||
pixman_vector_t vector;
|
||||
|
||||
pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
|
||||
pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
|
||||
pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
|
||||
|
||||
pixman_transform->matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
|
||||
pixman_transform->matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
|
||||
pixman_transform->matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
|
||||
|
||||
pixman_transform->matrix[2][0] = 0;
|
||||
pixman_transform->matrix[2][1] = 0;
|
||||
pixman_transform->matrix[2][2] = 1 << 16;
|
||||
|
||||
/* The conversion above breaks cairo's translation invariance:
|
||||
* a translation of (a, b) in device space translates to
|
||||
* a translation of (xx * a + xy * b, yx * a + yy * b)
|
||||
* for cairo, while pixman uses rounded versions of xx ... yy.
|
||||
* This error increases as a and b get larger.
|
||||
*
|
||||
* To compensate for this, we fix the point (0, 0) in pattern
|
||||
* space and adjust pixman's transform to agree with cairo's at
|
||||
* that point. */
|
||||
|
||||
/* Note: If we can't invert the transformation, skip the adjustment. */
|
||||
if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
/* find the device space coordinate that maps to (0, 0) */
|
||||
cairo_matrix_transform_point (&inv, &x, &y);
|
||||
|
||||
/* transform the resulting device space coordinate back
|
||||
* to the pattern space, using pixman's transform */
|
||||
vector.vector[0] = _cairo_fixed_16_16_from_double (x);
|
||||
vector.vector[1] = _cairo_fixed_16_16_from_double (y);
|
||||
vector.vector[2] = 1 << 16;
|
||||
|
||||
if (!pixman_transform_point_3d (pixman_transform, &vector))
|
||||
return;
|
||||
|
||||
/* Ideally, the vector should now be (0, 0). We can now compensate
|
||||
* for the resulting error */
|
||||
pixman_transform->matrix[0][2] -= vector.vector[0];
|
||||
pixman_transform->matrix[1][2] -= vector.vector[1];
|
||||
}
|
||||
}
|
||||
190
uppdev/plugin/cairo/lib/cairo-meta-surface-private.h
Normal file
190
uppdev/plugin/cairo/lib/cairo-meta-surface-private.h
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_META_SURFACE_H
|
||||
#define CAIRO_META_SURFACE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
typedef enum {
|
||||
/* The 5 basic drawing operations. */
|
||||
CAIRO_COMMAND_PAINT,
|
||||
CAIRO_COMMAND_MASK,
|
||||
CAIRO_COMMAND_STROKE,
|
||||
CAIRO_COMMAND_FILL,
|
||||
CAIRO_COMMAND_SHOW_TEXT_GLYPHS,
|
||||
|
||||
/* Other junk. For most of these, we should be able to assert that
|
||||
* they never get called except as part of fallbacks for the 5
|
||||
* basic drawing operations (which we implement already so the
|
||||
* fallbacks should never get triggered). So the plan is to
|
||||
* eliminate as many of these as possible. */
|
||||
|
||||
CAIRO_COMMAND_INTERSECT_CLIP_PATH
|
||||
|
||||
} cairo_command_type_t;
|
||||
|
||||
typedef enum {
|
||||
CAIRO_META_REGION_ALL,
|
||||
CAIRO_META_REGION_NATIVE,
|
||||
CAIRO_META_REGION_IMAGE_FALLBACK
|
||||
} cairo_meta_region_type_t;
|
||||
|
||||
typedef struct _cairo_command_header {
|
||||
cairo_command_type_t type;
|
||||
cairo_meta_region_type_t region;
|
||||
} cairo_command_header_t;
|
||||
|
||||
typedef struct _cairo_command_paint {
|
||||
cairo_command_header_t header;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
} cairo_command_paint_t;
|
||||
|
||||
typedef struct _cairo_command_mask {
|
||||
cairo_command_header_t header;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_pattern_union_t mask;
|
||||
} cairo_command_mask_t;
|
||||
|
||||
typedef struct _cairo_command_stroke {
|
||||
cairo_command_header_t header;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_stroke_style_t style;
|
||||
cairo_matrix_t ctm;
|
||||
cairo_matrix_t ctm_inverse;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
} cairo_command_stroke_t;
|
||||
|
||||
typedef struct _cairo_command_fill {
|
||||
cairo_command_header_t header;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
} cairo_command_fill_t;
|
||||
|
||||
typedef struct _cairo_command_show_text_glyphs {
|
||||
cairo_command_header_t header;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
char *utf8;
|
||||
int utf8_len;
|
||||
cairo_glyph_t *glyphs;
|
||||
unsigned int num_glyphs;
|
||||
cairo_text_cluster_t *clusters;
|
||||
int num_clusters;
|
||||
cairo_text_cluster_flags_t cluster_flags;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
} cairo_command_show_text_glyphs_t;
|
||||
|
||||
typedef struct _cairo_command_intersect_clip_path {
|
||||
cairo_command_header_t header;
|
||||
cairo_path_fixed_t *path_pointer;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
} cairo_command_intersect_clip_path_t;
|
||||
|
||||
typedef union _cairo_command {
|
||||
cairo_command_header_t header;
|
||||
|
||||
/* The 5 basic drawing operations. */
|
||||
cairo_command_paint_t paint;
|
||||
cairo_command_mask_t mask;
|
||||
cairo_command_stroke_t stroke;
|
||||
cairo_command_fill_t fill;
|
||||
cairo_command_show_text_glyphs_t show_text_glyphs;
|
||||
|
||||
/* The other junk. */
|
||||
cairo_command_intersect_clip_path_t intersect_clip_path;
|
||||
} cairo_command_t;
|
||||
|
||||
typedef struct _cairo_meta_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
cairo_content_t content;
|
||||
|
||||
/* A meta-surface is logically unbounded, but when used as a
|
||||
* source we need to render it to an image, so we need a size at
|
||||
* which to create that image. */
|
||||
int width_pixels;
|
||||
int height_pixels;
|
||||
|
||||
cairo_array_t commands;
|
||||
cairo_surface_t *commands_owner;
|
||||
|
||||
cairo_bool_t is_clipped;
|
||||
int replay_start_idx;
|
||||
} cairo_meta_surface_t;
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_meta_surface_create (cairo_content_t content,
|
||||
int width_pixels,
|
||||
int height_pixels);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_meta_surface_get_path (cairo_surface_t *surface,
|
||||
cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay_analyze_meta_pattern (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay_and_create_regions (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay_region (cairo_surface_t *surface,
|
||||
cairo_surface_t *target,
|
||||
cairo_meta_region_type_t region);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
||||
|
||||
#endif /* CAIRO_META_SURFACE_H */
|
||||
1010
uppdev/plugin/cairo/lib/cairo-meta-surface.c
Normal file
1010
uppdev/plugin/cairo/lib/cairo-meta-surface.c
Normal file
File diff suppressed because it is too large
Load diff
669
uppdev/plugin/cairo/lib/cairo-misc.c
Normal file
669
uppdev/plugin/cairo/lib/cairo-misc.c
Normal file
|
|
@ -0,0 +1,669 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
* Copyright © 2007 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
COMPILE_TIME_ASSERT (CAIRO_STATUS_LAST_STATUS < CAIRO_INT_STATUS_UNSUPPORTED);
|
||||
COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
|
||||
|
||||
/* Public stuff */
|
||||
|
||||
/**
|
||||
* cairo_status_to_string:
|
||||
* @status: a cairo status
|
||||
*
|
||||
* Provides a human-readable description of a #cairo_status_t.
|
||||
*
|
||||
* Returns: a string representation of the status
|
||||
*/
|
||||
const char *
|
||||
cairo_status_to_string (cairo_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
return "success";
|
||||
case CAIRO_STATUS_NO_MEMORY:
|
||||
return "out of memory";
|
||||
case CAIRO_STATUS_INVALID_RESTORE:
|
||||
return "cairo_restore without matching cairo_save";
|
||||
case CAIRO_STATUS_INVALID_POP_GROUP:
|
||||
return "cairo_pop_group without matching cairo_push_group";
|
||||
case CAIRO_STATUS_NO_CURRENT_POINT:
|
||||
return "no current point defined";
|
||||
case CAIRO_STATUS_INVALID_MATRIX:
|
||||
return "invalid matrix (not invertible)";
|
||||
case CAIRO_STATUS_INVALID_STATUS:
|
||||
return "invalid value for an input cairo_status_t";
|
||||
case CAIRO_STATUS_NULL_POINTER:
|
||||
return "NULL pointer";
|
||||
case CAIRO_STATUS_INVALID_STRING:
|
||||
return "input string not valid UTF-8";
|
||||
case CAIRO_STATUS_INVALID_PATH_DATA:
|
||||
return "input path data not valid";
|
||||
case CAIRO_STATUS_READ_ERROR:
|
||||
return "error while reading from input stream";
|
||||
case CAIRO_STATUS_WRITE_ERROR:
|
||||
return "error while writing to output stream";
|
||||
case CAIRO_STATUS_SURFACE_FINISHED:
|
||||
return "the target surface has been finished";
|
||||
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
|
||||
return "the surface type is not appropriate for the operation";
|
||||
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
|
||||
return "the pattern type is not appropriate for the operation";
|
||||
case CAIRO_STATUS_INVALID_CONTENT:
|
||||
return "invalid value for an input cairo_content_t";
|
||||
case CAIRO_STATUS_INVALID_FORMAT:
|
||||
return "invalid value for an input cairo_format_t";
|
||||
case CAIRO_STATUS_INVALID_VISUAL:
|
||||
return "invalid value for an input Visual*";
|
||||
case CAIRO_STATUS_FILE_NOT_FOUND:
|
||||
return "file not found";
|
||||
case CAIRO_STATUS_INVALID_DASH:
|
||||
return "invalid value for a dash setting";
|
||||
case CAIRO_STATUS_INVALID_DSC_COMMENT:
|
||||
return "invalid value for a DSC comment";
|
||||
case CAIRO_STATUS_INVALID_INDEX:
|
||||
return "invalid index passed to getter";
|
||||
case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
|
||||
return "clip region not representable in desired format";
|
||||
case CAIRO_STATUS_TEMP_FILE_ERROR:
|
||||
return "error creating or writing to a temporary file";
|
||||
case CAIRO_STATUS_INVALID_STRIDE:
|
||||
return "invalid value for stride";
|
||||
case CAIRO_STATUS_FONT_TYPE_MISMATCH:
|
||||
return "the font type is not appropriate for the operation";
|
||||
case CAIRO_STATUS_USER_FONT_IMMUTABLE:
|
||||
return "the user-font is immutable";
|
||||
case CAIRO_STATUS_USER_FONT_ERROR:
|
||||
return "error occurred in a user-font callback function";
|
||||
case CAIRO_STATUS_NEGATIVE_COUNT:
|
||||
return "negative number used where it is not allowed";
|
||||
case CAIRO_STATUS_INVALID_CLUSTERS:
|
||||
return "input clusters do not represent the accompanying text and glyph arrays";
|
||||
case CAIRO_STATUS_INVALID_SLANT:
|
||||
return "invalid value for an input #cairo_font_slant_t";
|
||||
case CAIRO_STATUS_INVALID_WEIGHT:
|
||||
return "input value for an input #cairo_font_weight_t";
|
||||
}
|
||||
|
||||
return "<unknown error status>";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* cairo_glyph_allocate:
|
||||
* @num_glyphs: number of glyphs to allocate
|
||||
*
|
||||
* Allocates an array of #cairo_glyph_t's.
|
||||
* This function is only useful in implementations of
|
||||
* #cairo_user_scaled_font_text_to_glyphs_func_t where the user
|
||||
* needs to allocate an array of glyphs that cairo will free.
|
||||
* For all other uses, user can use their own allocation method
|
||||
* for glyphs.
|
||||
*
|
||||
* This function returns %NULL if @num_glyphs is not positive,
|
||||
* or if out of memory. That means, the %NULL return value
|
||||
* signals out-of-memory only if @num_glyphs was positive.
|
||||
*
|
||||
* Returns: the newly allocated array of glyphs that should be
|
||||
* freed using cairo_glyph_free()
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
cairo_glyph_t *
|
||||
cairo_glyph_allocate (int num_glyphs)
|
||||
{
|
||||
if (num_glyphs <= 0)
|
||||
return NULL;
|
||||
|
||||
return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
}
|
||||
slim_hidden_def (cairo_glyph_allocate);
|
||||
|
||||
/**
|
||||
* cairo_glyph_free:
|
||||
* @glyphs: array of glyphs to free, or %NULL
|
||||
*
|
||||
* Frees an array of #cairo_glyph_t's allocated using cairo_glyph_allocate().
|
||||
* This function is only useful to free glyph array returned
|
||||
* by cairo_scaled_font_text_to_glyphs() where cairo returns
|
||||
* an array of glyphs that the user will free.
|
||||
* For all other uses, user can use their own allocation method
|
||||
* for glyphs.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
void
|
||||
cairo_glyph_free (cairo_glyph_t *glyphs)
|
||||
{
|
||||
if (glyphs)
|
||||
free (glyphs);
|
||||
}
|
||||
slim_hidden_def (cairo_glyph_free);
|
||||
|
||||
/**
|
||||
* cairo_text_cluster_allocate:
|
||||
* @num_clusters: number of text_clusters to allocate
|
||||
*
|
||||
* Allocates an array of #cairo_text_cluster_t's.
|
||||
* This function is only useful in implementations of
|
||||
* #cairo_user_scaled_font_text_to_glyphs_func_t where the user
|
||||
* needs to allocate an array of text clusters that cairo will free.
|
||||
* For all other uses, user can use their own allocation method
|
||||
* for text clusters.
|
||||
*
|
||||
* This function returns %NULL if @num_clusters is not positive,
|
||||
* or if out of memory. That means, the %NULL return value
|
||||
* signals out-of-memory only if @num_clusters was positive.
|
||||
*
|
||||
* Returns: the newly allocated array of text clusters that should be
|
||||
* freed using cairo_text_cluster_free()
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
cairo_text_cluster_t *
|
||||
cairo_text_cluster_allocate (int num_clusters)
|
||||
{
|
||||
if (num_clusters <= 0)
|
||||
return NULL;
|
||||
|
||||
return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
|
||||
}
|
||||
slim_hidden_def (cairo_text_cluster_allocate);
|
||||
|
||||
/**
|
||||
* cairo_text_cluster_free:
|
||||
* @clusters: array of text clusters to free, or %NULL
|
||||
*
|
||||
* Frees an array of #cairo_text_cluster's allocated using cairo_text_cluster_allocate().
|
||||
* This function is only useful to free text cluster array returned
|
||||
* by cairo_scaled_font_text_to_glyphs() where cairo returns
|
||||
* an array of text clusters that the user will free.
|
||||
* For all other uses, user can use their own allocation method
|
||||
* for text clusters.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
void
|
||||
cairo_text_cluster_free (cairo_text_cluster_t *clusters)
|
||||
{
|
||||
if (clusters)
|
||||
free (clusters);
|
||||
}
|
||||
slim_hidden_def (cairo_text_cluster_free);
|
||||
|
||||
|
||||
/* Private stuff */
|
||||
|
||||
/**
|
||||
* _cairo_validate_text_clusters:
|
||||
* @utf8: UTF-8 text
|
||||
* @utf8_len: length of @utf8 in bytes
|
||||
* @glyphs: array of glyphs
|
||||
* @num_glyphs: number of glyphs
|
||||
* @clusters: array of cluster mapping information
|
||||
* @num_clusters: number of clusters in the mapping
|
||||
* @cluster_flags: cluster flags
|
||||
*
|
||||
* Check that clusters cover the entire glyphs and utf8 arrays,
|
||||
* and that cluster boundaries are UTF-8 boundaries.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS upon success, or
|
||||
* %CAIRO_STATUS_INVALID_CLUSTERS on error.
|
||||
* The error is either invalid UTF-8 input,
|
||||
* or bad cluster mapping.
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_validate_text_clusters (const char *utf8,
|
||||
int utf8_len,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
const cairo_text_cluster_t *clusters,
|
||||
int num_clusters,
|
||||
cairo_text_cluster_flags_t cluster_flags)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned int n_bytes = 0;
|
||||
unsigned int n_glyphs = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_clusters; i++) {
|
||||
int cluster_bytes = clusters[i].num_bytes;
|
||||
int cluster_glyphs = clusters[i].num_glyphs;
|
||||
|
||||
if (cluster_bytes < 0 || cluster_glyphs < 0)
|
||||
goto BAD;
|
||||
|
||||
/* A cluster should cover at least one character or glyph.
|
||||
* I can't see any use for a 0,0 cluster.
|
||||
* I can't see an immediate use for a zero-text cluster
|
||||
* right now either, but they don't harm.
|
||||
* Zero-glyph clusters on the other hand are useful for
|
||||
* things like U+200C ZERO WIDTH NON-JOINER */
|
||||
if (cluster_bytes == 0 && cluster_glyphs == 0)
|
||||
goto BAD;
|
||||
|
||||
/* Since n_bytes and n_glyphs are unsigned, but the rest of
|
||||
* values involved are signed, we can detect overflow easily */
|
||||
if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs)
|
||||
goto BAD;
|
||||
|
||||
/* Make sure we've got valid UTF-8 for the cluster */
|
||||
status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL);
|
||||
if (status)
|
||||
return CAIRO_STATUS_INVALID_CLUSTERS;
|
||||
|
||||
n_bytes += cluster_bytes ;
|
||||
n_glyphs += cluster_glyphs;
|
||||
}
|
||||
|
||||
if (n_bytes != (unsigned int) utf8_len || n_glyphs != (unsigned int) num_glyphs) {
|
||||
BAD:
|
||||
return CAIRO_STATUS_INVALID_CLUSTERS;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_operator_bounded_by_mask:
|
||||
* @op: a #cairo_operator_t
|
||||
*
|
||||
* A bounded operator is one where mask pixel
|
||||
* of zero results in no effect on the destination image.
|
||||
*
|
||||
* Unbounded operators often require special handling; if you, for
|
||||
* example, draw trapezoids with an unbounded operator, the effect
|
||||
* extends past the bounding box of the trapezoids.
|
||||
*
|
||||
* Return value: %TRUE if the operator is bounded by the mask operand
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_operator_bounded_by_mask (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return TRUE;
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
case CAIRO_OPERATOR_IN:
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_operator_bounded_by_source:
|
||||
* @op: a #cairo_operator_t
|
||||
*
|
||||
* A bounded operator is one where source pixels of zero
|
||||
* (in all four components, r, g, b and a) effect no change
|
||||
* in the resulting destination image.
|
||||
*
|
||||
* Unbounded operators often require special handling; if you, for
|
||||
* example, copy a surface with the SOURCE operator, the effect
|
||||
* extends past the bounding box of the source surface.
|
||||
*
|
||||
* Return value: %TRUE if the operator is bounded by the source operand
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_operator_bounded_by_source (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return TRUE;
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
case CAIRO_OPERATOR_IN:
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_cairo_restrict_value (double *value, double min, double max)
|
||||
{
|
||||
if (*value < min)
|
||||
*value = min;
|
||||
else if (*value > max)
|
||||
*value = max;
|
||||
}
|
||||
|
||||
/* This function is identical to the C99 function lround(), except that it
|
||||
* performs arithmetic rounding (instead of away-from-zero rounding) and
|
||||
* has a valid input range of (INT_MIN, INT_MAX] instead of
|
||||
* [INT_MIN, INT_MAX]. It is much faster on both x86 and FPU-less systems
|
||||
* than other commonly used methods for rounding (lround, round, rint, lrint
|
||||
* or float (d + 0.5)).
|
||||
*
|
||||
* The reason why this function is much faster on x86 than other
|
||||
* methods is due to the fact that it avoids the fldcw instruction.
|
||||
* This instruction incurs a large performance penalty on modern Intel
|
||||
* processors due to how it prevents efficient instruction pipelining.
|
||||
*
|
||||
* The reason why this function is much faster on FPU-less systems is for
|
||||
* an entirely different reason. All common rounding methods involve multiple
|
||||
* floating-point operations. Each one of these operations has to be
|
||||
* emulated in software, which adds up to be a large performance penalty.
|
||||
* This function doesn't perform any floating-point calculations, and thus
|
||||
* avoids this penalty.
|
||||
*/
|
||||
int
|
||||
_cairo_lround (double d)
|
||||
{
|
||||
uint32_t top, shift_amount, output;
|
||||
union {
|
||||
double d;
|
||||
uint64_t ui64;
|
||||
uint32_t ui32[2];
|
||||
} u;
|
||||
|
||||
u.d = d;
|
||||
|
||||
/* If the integer word order doesn't match the float word order, we swap
|
||||
* the words of the input double. This is needed because we will be
|
||||
* treating the whole double as a 64-bit unsigned integer. Notice that we
|
||||
* use WORDS_BIGENDIAN to detect the integer word order, which isn't
|
||||
* exactly correct because WORDS_BIGENDIAN refers to byte order, not word
|
||||
* order. Thus, we are making the assumption that the byte order is the
|
||||
* same as the integer word order which, on the modern machines that we
|
||||
* care about, is OK.
|
||||
*/
|
||||
#if ( defined(FLOAT_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)) || \
|
||||
(!defined(FLOAT_WORDS_BIGENDIAN) && defined(WORDS_BIGENDIAN))
|
||||
{
|
||||
uint32_t temp = u.ui32[0];
|
||||
u.ui32[0] = u.ui32[1];
|
||||
u.ui32[1] = temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define MSW (0) /* Most Significant Word */
|
||||
#define LSW (1) /* Least Significant Word */
|
||||
#else
|
||||
#define MSW (1)
|
||||
#define LSW (0)
|
||||
#endif
|
||||
|
||||
/* By shifting the most significant word of the input double to the
|
||||
* right 20 places, we get the very "top" of the double where the exponent
|
||||
* and sign bit lie.
|
||||
*/
|
||||
top = u.ui32[MSW] >> 20;
|
||||
|
||||
/* Here, we calculate how much we have to shift the mantissa to normalize
|
||||
* it to an integer value. We extract the exponent "top" by masking out the
|
||||
* sign bit, then we calculate the shift amount by subtracting the exponent
|
||||
* from the bias. Notice that the correct bias for 64-bit doubles is
|
||||
* actually 1075, but we use 1053 instead for two reasons:
|
||||
*
|
||||
* 1) To perform rounding later on, we will first need the target
|
||||
* value in a 31.1 fixed-point format. Thus, the bias needs to be one
|
||||
* less: (1075 - 1: 1074).
|
||||
*
|
||||
* 2) To avoid shifting the mantissa as a full 64-bit integer (which is
|
||||
* costly on certain architectures), we break the shift into two parts.
|
||||
* First, the upper and lower parts of the mantissa are shifted
|
||||
* individually by a constant amount that all valid inputs will require
|
||||
* at the very least. This amount is chosen to be 21, because this will
|
||||
* allow the two parts of the mantissa to later be combined into a
|
||||
* single 32-bit representation, on which the remainder of the shift
|
||||
* will be performed. Thus, we decrease the bias by an additional 21:
|
||||
* (1074 - 21: 1053).
|
||||
*/
|
||||
shift_amount = 1053 - (top & 0x7FF);
|
||||
|
||||
/* We are done with the exponent portion in "top", so here we shift it off
|
||||
* the end.
|
||||
*/
|
||||
top >>= 11;
|
||||
|
||||
/* Before we perform any operations on the mantissa, we need to OR in
|
||||
* the implicit 1 at the top (see the IEEE-754 spec). We needn't mask
|
||||
* off the sign bit nor the exponent bits because these higher bits won't
|
||||
* make a bit of difference in the rest of our calculations.
|
||||
*/
|
||||
u.ui32[MSW] |= 0x100000;
|
||||
|
||||
/* If the input double is negative, we have to decrease the mantissa
|
||||
* by a hair. This is an important part of performing arithmetic rounding,
|
||||
* as negative numbers must round towards positive infinity in the
|
||||
* halfwase case of -x.5. Since "top" contains only the sign bit at this
|
||||
* point, we can just decrease the mantissa by the value of "top".
|
||||
*/
|
||||
u.ui64 -= top;
|
||||
|
||||
/* By decrementing "top", we create a bitmask with a value of either
|
||||
* 0x0 (if the input was negative) or 0xFFFFFFFF (if the input was positive
|
||||
* and thus the unsigned subtraction underflowed) that we'll use later.
|
||||
*/
|
||||
top--;
|
||||
|
||||
/* Here, we shift the mantissa by the constant value as described above.
|
||||
* We can emulate a 64-bit shift right by 21 through shifting the top 32
|
||||
* bits left 11 places and ORing in the bottom 32 bits shifted 21 places
|
||||
* to the right. Both parts of the mantissa are now packed into a single
|
||||
* 32-bit integer. Although we severely truncate the lower part in the
|
||||
* process, we still have enough significant bits to perform the conversion
|
||||
* without error (for all valid inputs).
|
||||
*/
|
||||
output = (u.ui32[MSW] << 11) | (u.ui32[LSW] >> 21);
|
||||
|
||||
/* Next, we perform the shift that converts the X.Y fixed-point number
|
||||
* currently found in "output" to the desired 31.1 fixed-point format
|
||||
* needed for the following rounding step. It is important to consider
|
||||
* all possible values for "shift_amount" at this point:
|
||||
*
|
||||
* - {shift_amount < 0} Since shift_amount is an unsigned integer, it
|
||||
* really can't have a value less than zero. But, if the shift_amount
|
||||
* calculation above caused underflow (which would happen with
|
||||
* input > INT_MAX or input <= INT_MIN) then shift_amount will now be
|
||||
* a very large number, and so this shift will result in complete
|
||||
* garbage. But that's OK, as the input was out of our range, so our
|
||||
* output is undefined.
|
||||
*
|
||||
* - {shift_amount > 31} If the magnitude of the input was very small
|
||||
* (i.e. |input| << 1.0), shift_amount will have a value greater than
|
||||
* 31. Thus, this shift will also result in garbage. After performing
|
||||
* the shift, we will zero-out "output" if this is the case.
|
||||
*
|
||||
* - {0 <= shift_amount < 32} In this case, the shift will properly convert
|
||||
* the mantissa into a 31.1 fixed-point number.
|
||||
*/
|
||||
output >>= shift_amount;
|
||||
|
||||
/* This is where we perform rounding with the 31.1 fixed-point number.
|
||||
* Since what we're after is arithmetic rounding, we simply add the single
|
||||
* fractional bit into the integer part of "output", and just keep the
|
||||
* integer part.
|
||||
*/
|
||||
output = (output >> 1) + (output & 1);
|
||||
|
||||
/* Here, we zero-out the result if the magnitude if the input was very small
|
||||
* (as explained in the section above). Notice that all input out of the
|
||||
* valid range is also caught by this condition, which means we produce 0
|
||||
* for all invalid input, which is a nice side effect.
|
||||
*
|
||||
* The most straightforward way to do this would be:
|
||||
*
|
||||
* if (shift_amount > 31)
|
||||
* output = 0;
|
||||
*
|
||||
* But we can use a little trick to avoid the potential branch. The
|
||||
* expression (shift_amount > 31) will be either 1 or 0, which when
|
||||
* decremented will be either 0x0 or 0xFFFFFFFF (unsigned underflow),
|
||||
* which can be used to conditionally mask away all the bits in "output"
|
||||
* (in the 0x0 case), effectively zeroing it out. Certain, compilers would
|
||||
* have done this for us automatically.
|
||||
*/
|
||||
output &= ((shift_amount > 31) - 1);
|
||||
|
||||
/* If the input double was a negative number, then we have to negate our
|
||||
* output. The most straightforward way to do this would be:
|
||||
*
|
||||
* if (!top)
|
||||
* output = -output;
|
||||
*
|
||||
* as "top" at this point is either 0x0 (if the input was negative) or
|
||||
* 0xFFFFFFFF (if the input was positive). But, we can use a trick to
|
||||
* avoid the branch. Observe that the following snippet of code has the
|
||||
* same effect as the reference snippet above:
|
||||
*
|
||||
* if (!top)
|
||||
* output = 0 - output;
|
||||
* else
|
||||
* output = output - 0;
|
||||
*
|
||||
* Armed with the bitmask found in "top", we can condense the two statements
|
||||
* into the following:
|
||||
*
|
||||
* output = (output & top) - (output & ~top);
|
||||
*
|
||||
* where, in the case that the input double was negative, "top" will be 0,
|
||||
* and the statement will be equivalent to:
|
||||
*
|
||||
* output = (0) - (output);
|
||||
*
|
||||
* and if the input double was positive, "top" will be 0xFFFFFFFF, and the
|
||||
* statement will be equivalent to:
|
||||
*
|
||||
* output = (output) - (0);
|
||||
*
|
||||
* Which, as pointed out earlier, is equivalent to the original reference
|
||||
* snippet.
|
||||
*/
|
||||
output = (output & top) - (output & ~top);
|
||||
|
||||
return output;
|
||||
#undef MSW
|
||||
#undef LSW
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* We require Windows 2000 features such as ETO_PDY */
|
||||
#if !defined(WINVER) || (WINVER < 0x0500)
|
||||
# define WINVER 0x0500
|
||||
#endif
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
|
||||
# define _WIN32_WINNT 0x0500
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
/* tmpfile() replacment for Windows.
|
||||
*
|
||||
* On Windows tmpfile() creates the file in the root directory. This
|
||||
* may fail due to unsufficient privileges.
|
||||
*/
|
||||
FILE *
|
||||
_cairo_win32_tmpfile (void)
|
||||
{
|
||||
DWORD path_len;
|
||||
WCHAR path_name[MAX_PATH + 1];
|
||||
WCHAR file_name[MAX_PATH + 1];
|
||||
HANDLE handle;
|
||||
int fd;
|
||||
FILE *fp;
|
||||
|
||||
path_len = GetTempPathW (MAX_PATH, path_name);
|
||||
if (path_len <= 0 || path_len >= MAX_PATH)
|
||||
return NULL;
|
||||
|
||||
if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
|
||||
return NULL;
|
||||
|
||||
handle = CreateFileW (file_name,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
DeleteFileW (file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = _open_osfhandle((intptr_t) handle, 0);
|
||||
if (fd < 0) {
|
||||
CloseHandle (handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fp = fdopen(fd, "w+b");
|
||||
if (fp == NULL) {
|
||||
_close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
239
uppdev/plugin/cairo/lib/cairo-mutex-impl-private.h
Normal file
239
uppdev/plugin/cairo/lib/cairo-mutex-impl-private.h
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005,2007 Red Hat, Inc.
|
||||
* Copyright © 2007 Mathias Hasselmann
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
* Behdad Esfahbod <behdad@behdad.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_MUTEX_IMPL_PRIVATE_H
|
||||
#define CAIRO_MUTEX_IMPL_PRIVATE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_LOCKDEP
|
||||
#include <lockdep.h>
|
||||
#endif
|
||||
|
||||
/* A fully qualified no-operation statement */
|
||||
#define CAIRO_MUTEX_IMPL_NOOP do {/*no-op*/} while (0)
|
||||
/* And one that evaluates it's argument once */
|
||||
#define CAIRO_MUTEX_IMPL_NOOP1(expr) do { if (expr) ; } while (0)
|
||||
|
||||
|
||||
/* Cairo mutex implementation:
|
||||
*
|
||||
* Any new mutex implementation needs to do the following:
|
||||
*
|
||||
* - Condition on the right header or feature. Headers are
|
||||
* preferred as eg. you still can use win32 mutex implementation
|
||||
* on a win32 system even if you do not compile the win32
|
||||
* surface/backend.
|
||||
*
|
||||
* - typedef #cairo_mutex_impl_t to the proper mutex type on your target
|
||||
* system. Note that you may or may not need to use a pointer,
|
||||
* depending on what kinds of initialization your mutex
|
||||
* implementation supports. No trailing semicolon needed.
|
||||
* You should be able to compile the following snippet (don't try
|
||||
* running it):
|
||||
*
|
||||
* <programlisting>
|
||||
* cairo_mutex_impl_t _cairo_some_mutex;
|
||||
* </programlisting>
|
||||
*
|
||||
* - #define %CAIRO_MUTEX_IMPL_<NAME> 1 with suitable name for your platform. You
|
||||
* can later use this symbol in cairo-system.c.
|
||||
*
|
||||
* - #define CAIRO_MUTEX_IMPL_LOCK(mutex) and CAIRO_MUTEX_IMPL_UNLOCK(mutex) to
|
||||
* proper statement to lock/unlock the mutex object passed in.
|
||||
* You can (and should) assume that the mutex is already
|
||||
* initialized, and is-not-already-locked/is-locked,
|
||||
* respectively. Use the "do { ... } while (0)" idiom if necessary.
|
||||
* No trailing semicolons are needed (in any macro you define here).
|
||||
* You should be able to compile the following snippet:
|
||||
*
|
||||
* <programlisting>
|
||||
* cairo_mutex_impl_t _cairo_some_mutex;
|
||||
*
|
||||
* if (1)
|
||||
* CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex);
|
||||
* else
|
||||
* CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex);
|
||||
* </programlisting>
|
||||
*
|
||||
* - #define %CAIRO_MUTEX_IMPL_NIL_INITIALIZER to something that can
|
||||
* initialize the #cairo_mutex_impl_t type you defined. Most of the
|
||||
* time one of 0, %NULL, or {} works. At this point
|
||||
* you should be able to compile the following snippet:
|
||||
*
|
||||
* <programlisting>
|
||||
* cairo_mutex_impl_t _cairo_some_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER;
|
||||
*
|
||||
* if (1)
|
||||
* CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex);
|
||||
* else
|
||||
* CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex);
|
||||
* </programlisting>
|
||||
*
|
||||
* - If the above code is not enough to initialize a mutex on
|
||||
* your platform, #define CAIRO_MUTEX_IMPL_INIT(mutex) to statement
|
||||
* to initialize the mutex (allocate resources, etc). Such that
|
||||
* you should be able to compile AND RUN the following snippet:
|
||||
*
|
||||
* <programlisting>
|
||||
* cairo_mutex_impl_t _cairo_some_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER;
|
||||
*
|
||||
* CAIRO_MUTEX_IMPL_INIT (_cairo_some_mutex);
|
||||
*
|
||||
* if (1)
|
||||
* CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex);
|
||||
* else
|
||||
* CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex);
|
||||
* </programlisting>
|
||||
*
|
||||
* - If you define CAIRO_MUTEX_IMPL_INIT(mutex), cairo will use it to
|
||||
* initialize all static mutex'es. If for any reason that should
|
||||
* not happen (eg. %CAIRO_MUTEX_IMPL_INIT is just a faster way than
|
||||
* what cairo does using %CAIRO_MUTEX_IMPL_NIL_INITIALIZER), then
|
||||
* <programlisting>
|
||||
* #define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP
|
||||
* </programlisting>
|
||||
*
|
||||
* - If your system supports freeing a mutex object (deallocating
|
||||
* resources, etc), then #define CAIRO_MUTEX_IMPL_FINI(mutex) to do
|
||||
* that.
|
||||
*
|
||||
* - If you define CAIRO_MUTEX_IMPL_FINI(mutex), cairo will use it to
|
||||
* define a finalizer function to finalize all static mutex'es.
|
||||
* However, it's up to you to call CAIRO_MUTEX_IMPL_FINALIZE() at
|
||||
* proper places, eg. when the system is unloading the cairo library.
|
||||
* So, if for any reason finalizing static mutex'es is not needed
|
||||
* (eg. you never call CAIRO_MUTEX_IMPL_FINALIZE()), then
|
||||
* <programlisting>
|
||||
* #define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP
|
||||
* </programlisting>
|
||||
*
|
||||
* - That is all. If for any reason you think the above API is
|
||||
* not enough to implement #cairo_mutex_impl_t on your system, please
|
||||
* stop and write to the cairo mailing list about it. DO NOT
|
||||
* poke around cairo-mutex-private.h for possible solutions.
|
||||
*/
|
||||
|
||||
#if CAIRO_NO_MUTEX
|
||||
|
||||
/* No mutexes */
|
||||
|
||||
typedef int cairo_mutex_impl_t;
|
||||
|
||||
# define CAIRO_MUTEX_IMPL_NO 1
|
||||
# define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex)
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex)
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0
|
||||
|
||||
#elif HAVE_PTHREAD_H /*******************************************************/
|
||||
|
||||
# include <pthread.h>
|
||||
|
||||
typedef pthread_mutex_t cairo_mutex_impl_t;
|
||||
|
||||
# define CAIRO_MUTEX_IMPL_PTHREAD 1
|
||||
#if HAVE_LOCKDEP
|
||||
/* expose all mutexes to the validator */
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) pthread_mutex_init (&(mutex), NULL)
|
||||
#endif
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) pthread_mutex_lock (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
|
||||
#if HAVE_LOCKDEP
|
||||
# define CAIRO_MUTEX_IS_LOCKED(mutex) LOCKDEP_IS_LOCKED (&(mutex))
|
||||
# define CAIRO_MUTEX_IS_UNLOCKED(mutex) LOCKDEP_IS_UNLOCKED (&(mutex))
|
||||
#endif
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) pthread_mutex_destroy (&(mutex))
|
||||
#if ! HAVE_LOCKDEP
|
||||
# define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP
|
||||
#endif
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
#elif defined(HAVE_WINDOWS_H) || defined(_MSC_VER) /*************************/
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
typedef CRITICAL_SECTION cairo_mutex_impl_t;
|
||||
|
||||
# define CAIRO_MUTEX_IMPL_WIN32 1
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) EnterCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) LeaveCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) DeleteCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 }
|
||||
|
||||
#elif defined __OS2__ /******************************************************/
|
||||
|
||||
# define INCL_BASE
|
||||
# define INCL_PM
|
||||
# include <os2.h>
|
||||
|
||||
typedef HMTX cairo_mutex_impl_t;
|
||||
|
||||
# define CAIRO_MUTEX_IMPL_OS2 1
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT)
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) DosReleaseMutexSem(mutex)
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE)
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) DosCloseMutexSem (mutex)
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0
|
||||
|
||||
#elif CAIRO_HAS_BEOS_SURFACE /***********************************************/
|
||||
|
||||
typedef BLocker* cairo_mutex_impl_t;
|
||||
|
||||
# define CAIRO_MUTEX_IMPL_BEOS 1
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) (mutex)->Lock()
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) (mutex)->Unlock()
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) (mutex) = new BLocker()
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) delete (mutex)
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER NULL
|
||||
|
||||
#else /**********************************************************************/
|
||||
|
||||
# error "XXX: No mutex implementation found. Cairo will not work with multiple threads. Define CAIRO_NO_MUTEX to 1 to acknowledge and accept this limitation and compile cairo without thread-safety support."
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
59
uppdev/plugin/cairo/lib/cairo-mutex-list-private.h
Normal file
59
uppdev/plugin/cairo/lib/cairo-mutex-list-private.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Mathias Hasselmann
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_FEATURES_H
|
||||
/* This block is to just make this header file standalone */
|
||||
#define CAIRO_MUTEX_DECLARE(mutex)
|
||||
#endif
|
||||
|
||||
CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_pattern_cache_lock)
|
||||
CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock)
|
||||
|
||||
CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex)
|
||||
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
|
||||
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
|
||||
#endif
|
||||
|
||||
#if CAIRO_HAS_XLIB_SURFACE
|
||||
CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
|
||||
#endif
|
||||
|
||||
#if !defined (HAS_ATOMIC_OPS) || defined (ATOMIC_OP_NEEDS_MEMORY_BARRIER)
|
||||
CAIRO_MUTEX_DECLARE (_cairo_atomic_mutex)
|
||||
#endif
|
||||
|
||||
/* Undefine, to err on unintended inclusion */
|
||||
#undef CAIRO_MUTEX_DECLARE
|
||||
67
uppdev/plugin/cairo/lib/cairo-mutex-private.h
Normal file
67
uppdev/plugin/cairo/lib/cairo-mutex-private.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005,2007 Red Hat, Inc.
|
||||
* Copyright © 2007 Mathias Hasselmann
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
* Behdad Esfahbod <behdad@behdad.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_MUTEX_PRIVATE_H
|
||||
#define CAIRO_MUTEX_PRIVATE_H
|
||||
|
||||
#include "cairo-mutex-type-private.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
|
||||
cairo_private void _cairo_mutex_initialize (void);
|
||||
#endif
|
||||
#if _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
|
||||
cairo_private void _cairo_mutex_finalize (void);
|
||||
#endif
|
||||
/* only if using static initializer and/or finalizer define the boolean */
|
||||
#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
|
||||
cairo_private extern cairo_bool_t _cairo_mutex_initialized;
|
||||
#endif
|
||||
|
||||
/* Finally, extern the static mutexes and undef */
|
||||
|
||||
#define CAIRO_MUTEX_DECLARE(mutex) cairo_private extern cairo_mutex_t mutex;
|
||||
#include "cairo-mutex-list-private.h"
|
||||
#undef CAIRO_MUTEX_DECLARE
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
187
uppdev/plugin/cairo/lib/cairo-mutex-type-private.h
Normal file
187
uppdev/plugin/cairo/lib/cairo-mutex-type-private.h
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005,2007 Red Hat, Inc.
|
||||
* Copyright © 2007 Mathias Hasselmann
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
* Behdad Esfahbod <behdad@behdad.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_MUTEX_TYPE_PRIVATE_H
|
||||
#define CAIRO_MUTEX_TYPE_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-mutex-impl-private.h"
|
||||
|
||||
/* Only the following three are mandatory at this point */
|
||||
#ifndef CAIRO_MUTEX_IMPL_LOCK
|
||||
# error "CAIRO_MUTEX_IMPL_LOCK not defined. Check cairo-mutex-impl-private.h."
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_UNLOCK
|
||||
# error "CAIRO_MUTEX_IMPL_UNLOCK not defined. Check cairo-mutex-impl-private.h."
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_NIL_INITIALIZER
|
||||
# error "CAIRO_MUTEX_IMPL_NIL_INITIALIZER not defined. Check cairo-mutex-impl-private.h."
|
||||
#endif
|
||||
|
||||
|
||||
/* make sure implementations don't fool us: we decide these ourself */
|
||||
#undef _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
|
||||
#undef _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
|
||||
|
||||
|
||||
#ifdef CAIRO_MUTEX_IMPL_INIT
|
||||
|
||||
/* If %CAIRO_MUTEX_IMPL_INIT is defined, we may need to initialize all
|
||||
* static mutex'es. */
|
||||
# ifndef CAIRO_MUTEX_IMPL_INITIALIZE
|
||||
# define CAIRO_MUTEX_IMPL_INITIALIZE() do { \
|
||||
if (!_cairo_mutex_initialized) \
|
||||
_cairo_mutex_initialize (); \
|
||||
} while(0)
|
||||
|
||||
/* and make sure we implement the above */
|
||||
# define _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER 1
|
||||
# endif /* CAIRO_MUTEX_IMPL_INITIALIZE */
|
||||
|
||||
#else /* no CAIRO_MUTEX_IMPL_INIT */
|
||||
|
||||
/* Otherwise we probably don't need to initialize static mutex'es, */
|
||||
# ifndef CAIRO_MUTEX_IMPL_INITIALIZE
|
||||
# define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP
|
||||
# endif /* CAIRO_MUTEX_IMPL_INITIALIZE */
|
||||
|
||||
/* and dynamic ones can be initialized using the static initializer. */
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) do { \
|
||||
cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER; \
|
||||
memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* CAIRO_MUTEX_IMPL_INIT */
|
||||
|
||||
#ifdef CAIRO_MUTEX_IMPL_FINI
|
||||
|
||||
/* If %CAIRO_MUTEX_IMPL_FINI is defined, we may need to finalize all
|
||||
* static mutex'es. */
|
||||
# ifndef CAIRO_MUTEX_IMPL_FINALIZE
|
||||
# define CAIRO_MUTEX_IMPL_FINALIZE() do { \
|
||||
if (_cairo_mutex_initialized) \
|
||||
_cairo_mutex_finalize (); \
|
||||
} while(0)
|
||||
|
||||
/* and make sure we implement the above */
|
||||
# define _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER 1
|
||||
# endif /* CAIRO_MUTEX_IMPL_FINALIZE */
|
||||
|
||||
#else /* no CAIRO_MUTEX_IMPL_FINI */
|
||||
|
||||
/* Otherwise we probably don't need to finalize static mutex'es, */
|
||||
# ifndef CAIRO_MUTEX_IMPL_FINALIZE
|
||||
# define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP
|
||||
# endif /* CAIRO_MUTEX_IMPL_FINALIZE */
|
||||
|
||||
/* neither do the dynamic ones. */
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex)
|
||||
|
||||
#endif /* CAIRO_MUTEX_IMPL_FINI */
|
||||
|
||||
|
||||
#ifndef _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
|
||||
#define _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER 0
|
||||
#endif
|
||||
#ifndef _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
|
||||
#define _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Make sure everything we want is defined */
|
||||
#ifndef CAIRO_MUTEX_IMPL_INITIALIZE
|
||||
# error "CAIRO_MUTEX_IMPL_INITIALIZE not defined"
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_FINALIZE
|
||||
# error "CAIRO_MUTEX_IMPL_FINALIZE not defined"
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_LOCK
|
||||
# error "CAIRO_MUTEX_IMPL_LOCK not defined"
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_UNLOCK
|
||||
# error "CAIRO_MUTEX_IMPL_UNLOCK not defined"
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_INIT
|
||||
# error "CAIRO_MUTEX_IMPL_INIT not defined"
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_FINI
|
||||
# error "CAIRO_MUTEX_IMPL_FINI not defined"
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IMPL_NIL_INITIALIZER
|
||||
# error "CAIRO_MUTEX_IMPL_NIL_INITIALIZER not defined"
|
||||
#endif
|
||||
|
||||
|
||||
/* Public interface. */
|
||||
|
||||
/* By default it simply uses the implementation provided.
|
||||
* But we can provide for debugging features by overriding them */
|
||||
|
||||
#ifndef CAIRO_MUTEX_DEBUG
|
||||
typedef cairo_mutex_impl_t cairo_mutex_t;
|
||||
#else
|
||||
# define cairo_mutex_t cairo_mutex_impl_t
|
||||
#endif
|
||||
|
||||
#define CAIRO_MUTEX_INITIALIZE CAIRO_MUTEX_IMPL_INITIALIZE
|
||||
#define CAIRO_MUTEX_FINALIZE CAIRO_MUTEX_IMPL_FINALIZE
|
||||
#define CAIRO_MUTEX_LOCK CAIRO_MUTEX_IMPL_LOCK
|
||||
#define CAIRO_MUTEX_UNLOCK CAIRO_MUTEX_IMPL_UNLOCK
|
||||
#define CAIRO_MUTEX_INIT CAIRO_MUTEX_IMPL_INIT
|
||||
#define CAIRO_MUTEX_FINI CAIRO_MUTEX_IMPL_FINI
|
||||
#define CAIRO_MUTEX_NIL_INITIALIZER CAIRO_MUTEX_IMPL_NIL_INITIALIZER
|
||||
|
||||
#ifndef CAIRO_MUTEX_IS_LOCKED
|
||||
# define CAIRO_MUTEX_IS_LOCKED(name) 1
|
||||
#endif
|
||||
#ifndef CAIRO_MUTEX_IS_UNLOCKED
|
||||
# define CAIRO_MUTEX_IS_UNLOCKED(name) 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Debugging support */
|
||||
|
||||
#ifdef CAIRO_MUTEX_DEBUG
|
||||
|
||||
/* TODO add mutex debugging facilities here (eg deadlock detection) */
|
||||
|
||||
#endif /* CAIRO_MUTEX_DEBUG */
|
||||
|
||||
#endif
|
||||
82
uppdev/plugin/cairo/lib/cairo-mutex.c
Normal file
82
uppdev/plugin/cairo/lib/cairo-mutex.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Mathias Hasselmann
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-mutex-private.h"
|
||||
|
||||
#define CAIRO_MUTEX_DECLARE(mutex) cairo_mutex_t mutex = CAIRO_MUTEX_NIL_INITIALIZER;
|
||||
#include "cairo-mutex-list-private.h"
|
||||
#undef CAIRO_MUTEX_DECLARE
|
||||
|
||||
#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
|
||||
|
||||
# if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
|
||||
# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE FALSE
|
||||
# else
|
||||
# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE TRUE
|
||||
# endif
|
||||
|
||||
cairo_bool_t _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE;
|
||||
|
||||
# undef _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE
|
||||
|
||||
#endif
|
||||
|
||||
#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
|
||||
void _cairo_mutex_initialize (void)
|
||||
{
|
||||
if (_cairo_mutex_initialized)
|
||||
return;
|
||||
|
||||
_cairo_mutex_initialized = TRUE;
|
||||
|
||||
#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_INIT (mutex);
|
||||
#include "cairo-mutex-list-private.h"
|
||||
#undef CAIRO_MUTEX_DECLARE
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
|
||||
void _cairo_mutex_finalize (void)
|
||||
{
|
||||
if (!_cairo_mutex_initialized)
|
||||
return;
|
||||
|
||||
_cairo_mutex_initialized = FALSE;
|
||||
|
||||
#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_FINI (mutex);
|
||||
#include "cairo-mutex-list-private.h"
|
||||
#undef CAIRO_MUTEX_DECLARE
|
||||
}
|
||||
#endif
|
||||
77
uppdev/plugin/cairo/lib/cairo-os2-private.h
Normal file
77
uppdev/plugin/cairo/lib/cairo-os2-private.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* vim: set sw=4 sts=4 et cin: */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright (c) 2005-2006 netlabs.org
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Doodle <doodle@scenergy.dfmk.hu>
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_OS2_PRIVATE_H
|
||||
#define CAIRO_OS2_PRIVATE_H
|
||||
|
||||
#include "cairo-os2.h"
|
||||
#include "cairoint.h"
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSSEMAPHORES
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#ifdef __WATCOMC__
|
||||
# include <os2.h>
|
||||
#else
|
||||
# include <os2emx.h>
|
||||
#endif
|
||||
|
||||
typedef struct _cairo_os2_surface
|
||||
{
|
||||
cairo_surface_t base;
|
||||
|
||||
/* Mutex semaphore to protect private fields from concurrent access */
|
||||
HMTX hmtx_use_private_fields;
|
||||
/* Private fields: */
|
||||
HPS hps_client_window;
|
||||
HWND hwnd_client_window;
|
||||
BITMAPINFO2 bitmap_info;
|
||||
unsigned char *pixels;
|
||||
cairo_image_surface_t *image_surface;
|
||||
int pixel_array_lend_count;
|
||||
HEV hev_pixel_array_came_back;
|
||||
|
||||
RECTL rcl_dirty_area;
|
||||
cairo_bool_t dirty_area_present;
|
||||
|
||||
/* General flags: */
|
||||
cairo_bool_t blit_as_changes;
|
||||
} cairo_os2_surface_t;
|
||||
|
||||
#endif /* CAIRO_OS2_PRIVATE_H */
|
||||
1351
uppdev/plugin/cairo/lib/cairo-os2-surface.c
Normal file
1351
uppdev/plugin/cairo/lib/cairo-os2-surface.c
Normal file
File diff suppressed because it is too large
Load diff
88
uppdev/plugin/cairo/lib/cairo-os2.h
Normal file
88
uppdev/plugin/cairo/lib/cairo-os2.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* vim: set sw=4 sts=4 et cin: */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright (c) 2005-2006 netlabs.org
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Doodle <doodle@scenergy.dfmk.hu>
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
*/
|
||||
|
||||
#ifndef _CAIRO_OS2_H_
|
||||
#define _CAIRO_OS2_H_
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
/* The OS/2 Specific Cairo API */
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_init (void);
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_fini (void);
|
||||
|
||||
#if CAIRO_HAS_OS2_SURFACE
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_os2_surface_create (HPS hps_client_window,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_set_hwnd (cairo_surface_t *surface,
|
||||
HWND hwnd_client_window);
|
||||
|
||||
cairo_public int
|
||||
cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
int new_width,
|
||||
int new_height,
|
||||
int timeout);
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_refresh_window (cairo_surface_t *surface,
|
||||
HPS hps_begin_paint,
|
||||
PRECTL prcl_begin_paint_rect);
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface,
|
||||
cairo_bool_t manual_refresh);
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface);
|
||||
|
||||
#else /* CAIRO_HAS_OS2_SURFACE */
|
||||
# error Cairo was not compiled with support for the OS/2 backend
|
||||
#endif /* CAIRO_HAS_OS2_SURFACE */
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* _CAIRO_OS2_H_ */
|
||||
176
uppdev/plugin/cairo/lib/cairo-output-stream-private.h
Normal file
176
uppdev/plugin/cairo/lib/cairo-output-stream-private.h
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Author(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_OUTPUT_STREAM_PRIVATE_H
|
||||
#define CAIRO_OUTPUT_STREAM_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef cairo_status_t (*cairo_output_stream_write_func_t) (cairo_output_stream_t *output_stream,
|
||||
const unsigned char *data,
|
||||
unsigned int length);
|
||||
|
||||
typedef cairo_status_t (*cairo_output_stream_close_func_t) (cairo_output_stream_t *output_stream);
|
||||
|
||||
struct _cairo_output_stream {
|
||||
cairo_output_stream_write_func_t write_func;
|
||||
cairo_output_stream_close_func_t close_func;
|
||||
unsigned long position;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t closed;
|
||||
};
|
||||
|
||||
extern const cairo_private cairo_output_stream_t _cairo_output_stream_nil;
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_init (cairo_output_stream_t *stream,
|
||||
cairo_output_stream_write_func_t write_func,
|
||||
cairo_output_stream_close_func_t close_func);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_fini (cairo_output_stream_t *stream);
|
||||
|
||||
|
||||
/* We already have the following declared in cairo.h:
|
||||
|
||||
typedef cairo_status_t (*cairo_write_func_t) (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length);
|
||||
*/
|
||||
typedef cairo_status_t (*cairo_close_func_t) (void *closure);
|
||||
|
||||
|
||||
/* This function never returns %NULL. If an error occurs (NO_MEMORY)
|
||||
* while trying to create the output stream this function returns a
|
||||
* valid pointer to a nil output stream.
|
||||
*
|
||||
* Note that even with a nil surface, the close_func callback will be
|
||||
* called by a call to _cairo_output_stream_close or
|
||||
* _cairo_output_stream_destroy.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create (cairo_write_func_t write_func,
|
||||
cairo_close_func_t close_func,
|
||||
void *closure);
|
||||
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create_in_error (cairo_status_t status);
|
||||
|
||||
/* Returns the final status value associated with this object, just
|
||||
* before its last gasp. This final status value will capture any
|
||||
* status failure returned by the stream's close_func as well. */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream);
|
||||
|
||||
/* Returns the final status value associated with this object, just
|
||||
* before its last gasp. This final status value will capture any
|
||||
* status failure returned by the stream's close_func as well. */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_write (cairo_output_stream_t *stream,
|
||||
const void *data, size_t length);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
||||
const unsigned char *data,
|
||||
size_t length);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *fmt,
|
||||
va_list ap) CAIRO_PRINTF_FORMAT ( 2, 0);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_printf (cairo_output_stream_t *stream,
|
||||
const char *fmt,
|
||||
...) CAIRO_PRINTF_FORMAT (2, 3);
|
||||
|
||||
cairo_private long
|
||||
_cairo_output_stream_get_position (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_get_status (cairo_output_stream_t *stream);
|
||||
|
||||
/* This function never returns %NULL. If an error occurs (NO_MEMORY or
|
||||
* WRITE_ERROR) while trying to create the output stream this function
|
||||
* returns a valid pointer to a nil output stream.
|
||||
*
|
||||
* Note: Even if a nil surface is returned, the caller should still
|
||||
* call _cairo_output_stream_destroy (or _cairo_output_stream_close at
|
||||
* least) in order to ensure that everything is properly cleaned up.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_filename (const char *filename);
|
||||
|
||||
/* This function never returns %NULL. If an error occurs (NO_MEMORY or
|
||||
* WRITE_ERROR) while trying to create the output stream this function
|
||||
* returns a valid pointer to a nil output stream.
|
||||
*
|
||||
* The caller still "owns" file and is responsible for calling fclose
|
||||
* on it when finished. The stream will not do this itself.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (FILE *file);
|
||||
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_memory_stream_create (void);
|
||||
|
||||
cairo_private void
|
||||
_cairo_memory_stream_copy (cairo_output_stream_t *base,
|
||||
cairo_output_stream_t *dest);
|
||||
|
||||
cairo_private int
|
||||
_cairo_memory_stream_length (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_null_stream_create (void);
|
||||
|
||||
/* cairo-base85-stream.c */
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output);
|
||||
|
||||
/* cairo-deflate-stream.c */
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_deflate_stream_create (cairo_output_stream_t *output);
|
||||
|
||||
|
||||
#endif /* CAIRO_OUTPUT_STREAM_PRIVATE_H */
|
||||
707
uppdev/plugin/cairo/lib/cairo-output-stream.c
Normal file
707
uppdev/plugin/cairo/lib/cairo-output-stream.c
Normal file
|
|
@ -0,0 +1,707 @@
|
|||
/* cairo-output-stream.c: Output stream abstraction
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Author(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#define _BSD_SOURCE /* for snprintf() */
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-output-stream-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Numbers printed with %f are printed with this number of significant
|
||||
* digits after the decimal.
|
||||
*/
|
||||
#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
|
||||
|
||||
/* Numbers printed with %g are assumed to only have %CAIRO_FIXED_FRAC_BITS
|
||||
* bits of precision available after the decimal point.
|
||||
*
|
||||
* FIXED_POINT_DECIMAL_DIGITS specifies the minimum number of decimal
|
||||
* digits after the decimal point required to preserve the available
|
||||
* precision.
|
||||
*
|
||||
* The conversion is:
|
||||
*
|
||||
* <programlisting>
|
||||
* FIXED_POINT_DECIMAL_DIGITS = ceil( CAIRO_FIXED_FRAC_BITS * ln(2)/ln(10) )
|
||||
* </programlisting>
|
||||
*
|
||||
* We can replace ceil(x) with (int)(x+1) since x will never be an
|
||||
* integer for any likely value of %CAIRO_FIXED_FRAC_BITS.
|
||||
*/
|
||||
#define FIXED_POINT_DECIMAL_DIGITS ((int)(CAIRO_FIXED_FRAC_BITS*0.301029996 + 1))
|
||||
|
||||
void
|
||||
_cairo_output_stream_init (cairo_output_stream_t *stream,
|
||||
cairo_output_stream_write_func_t write_func,
|
||||
cairo_output_stream_close_func_t close_func)
|
||||
{
|
||||
stream->write_func = write_func;
|
||||
stream->close_func = close_func;
|
||||
stream->position = 0;
|
||||
stream->status = CAIRO_STATUS_SUCCESS;
|
||||
stream->closed = FALSE;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_output_stream_fini (cairo_output_stream_t *stream)
|
||||
{
|
||||
return _cairo_output_stream_close (stream);
|
||||
}
|
||||
|
||||
const cairo_output_stream_t _cairo_output_stream_nil = {
|
||||
NULL, /* write_func */
|
||||
NULL, /* close_func */
|
||||
0, /* position */
|
||||
CAIRO_STATUS_NO_MEMORY,
|
||||
FALSE /* closed */
|
||||
};
|
||||
|
||||
static const cairo_output_stream_t _cairo_output_stream_nil_write_error = {
|
||||
NULL, /* write_func */
|
||||
NULL, /* close_func */
|
||||
0, /* position */
|
||||
CAIRO_STATUS_WRITE_ERROR,
|
||||
FALSE /* closed */
|
||||
};
|
||||
|
||||
typedef struct _cairo_output_stream_with_closure {
|
||||
cairo_output_stream_t base;
|
||||
cairo_write_func_t write_func;
|
||||
cairo_close_func_t close_func;
|
||||
void *closure;
|
||||
} cairo_output_stream_with_closure_t;
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
closure_write (cairo_output_stream_t *stream,
|
||||
const unsigned char *data, unsigned int length)
|
||||
{
|
||||
cairo_output_stream_with_closure_t *stream_with_closure =
|
||||
(cairo_output_stream_with_closure_t *) stream;
|
||||
|
||||
if (stream_with_closure->write_func == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return stream_with_closure->write_func (stream_with_closure->closure,
|
||||
data, length);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
closure_close (cairo_output_stream_t *stream)
|
||||
{
|
||||
cairo_output_stream_with_closure_t *stream_with_closure =
|
||||
(cairo_output_stream_with_closure_t *) stream;
|
||||
|
||||
if (stream_with_closure->close_func != NULL)
|
||||
return stream_with_closure->close_func (stream_with_closure->closure);
|
||||
else
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create (cairo_write_func_t write_func,
|
||||
cairo_close_func_t close_func,
|
||||
void *closure)
|
||||
{
|
||||
cairo_output_stream_with_closure_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_output_stream_with_closure_t));
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, closure_write, closure_close);
|
||||
stream->write_func = write_func;
|
||||
stream->close_func = close_func;
|
||||
stream->closure = closure;
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create_in_error (cairo_status_t status)
|
||||
{
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
/* check for the common ones */
|
||||
if (status == CAIRO_STATUS_NO_MEMORY)
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
if (status == CAIRO_STATUS_WRITE_ERROR)
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
|
||||
|
||||
stream = malloc (sizeof (cairo_output_stream_t));
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (stream, NULL, NULL);
|
||||
stream->status = status;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (stream->closed)
|
||||
return stream->status;
|
||||
|
||||
if (stream == &_cairo_output_stream_nil ||
|
||||
stream == &_cairo_output_stream_nil_write_error)
|
||||
{
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
if (stream->close_func) {
|
||||
status = stream->close_func (stream);
|
||||
/* Don't overwrite a pre-existing status failure. */
|
||||
if (stream->status == CAIRO_STATUS_SUCCESS)
|
||||
stream->status = status;
|
||||
}
|
||||
|
||||
stream->closed = TRUE;
|
||||
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (stream != NULL);
|
||||
|
||||
if (stream == &_cairo_output_stream_nil ||
|
||||
stream == &_cairo_output_stream_nil_write_error)
|
||||
{
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
status = _cairo_output_stream_fini (stream);
|
||||
free (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_write (cairo_output_stream_t *stream,
|
||||
const void *data, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
stream->status = stream->write_func (stream, data, length);
|
||||
stream->position += length;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
||||
const unsigned char *data,
|
||||
size_t length)
|
||||
{
|
||||
const char hex_chars[] = "0123456789abcdef";
|
||||
char buffer[2];
|
||||
unsigned int i, column;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
for (i = 0, column = 0; i < length; i++, column++) {
|
||||
if (column == 38) {
|
||||
_cairo_output_stream_write (stream, "\n", 1);
|
||||
column = 0;
|
||||
}
|
||||
buffer[0] = hex_chars[(data[i] >> 4) & 0x0f];
|
||||
buffer[1] = hex_chars[data[i] & 0x0f];
|
||||
_cairo_output_stream_write (stream, buffer, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Format a double in a locale independent way and trim trailing
|
||||
* zeros. Based on code from Alex Larson <alexl@redhat.com>.
|
||||
* http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
|
||||
*
|
||||
* The code in the patch is copyright Red Hat, Inc under the LGPL, but
|
||||
* has been relicensed under the LGPL/MPL dual license for inclusion
|
||||
* into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
static void
|
||||
_cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precision)
|
||||
{
|
||||
struct lconv *locale_data;
|
||||
const char *decimal_point;
|
||||
int decimal_point_len;
|
||||
char *p;
|
||||
int decimal_len;
|
||||
int num_zeros, decimal_digits;
|
||||
|
||||
/* Omit the minus sign from negative zero. */
|
||||
if (d == 0.0)
|
||||
d = 0.0;
|
||||
|
||||
locale_data = localeconv ();
|
||||
decimal_point = locale_data->decimal_point;
|
||||
decimal_point_len = strlen (decimal_point);
|
||||
|
||||
assert (decimal_point_len != 0);
|
||||
|
||||
if (limited_precision) {
|
||||
snprintf (buffer, size, "%.*f", FIXED_POINT_DECIMAL_DIGITS, d);
|
||||
} else {
|
||||
/* Using "%f" to print numbers less than 0.1 will result in
|
||||
* reduced precision due to the default 6 digits after the
|
||||
* decimal point.
|
||||
*
|
||||
* For numbers is < 0.1, we print with maximum precision and count
|
||||
* the number of zeros between the decimal point and the first
|
||||
* significant digit. We then print the number again with the
|
||||
* number of decimal places that gives us the required number of
|
||||
* significant digits. This ensures the number is correctly
|
||||
* rounded.
|
||||
*/
|
||||
if (fabs (d) >= 0.1) {
|
||||
snprintf (buffer, size, "%f", d);
|
||||
} else {
|
||||
snprintf (buffer, size, "%.18f", d);
|
||||
p = buffer;
|
||||
|
||||
if (*p == '+' || *p == '-')
|
||||
p++;
|
||||
|
||||
while (isdigit (*p))
|
||||
p++;
|
||||
|
||||
if (strncmp (p, decimal_point, decimal_point_len) == 0)
|
||||
p += decimal_point_len;
|
||||
|
||||
num_zeros = 0;
|
||||
while (*p++ == '0')
|
||||
num_zeros++;
|
||||
|
||||
decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
|
||||
|
||||
if (decimal_digits < 18)
|
||||
snprintf (buffer, size, "%.*f", decimal_digits, d);
|
||||
}
|
||||
}
|
||||
p = buffer;
|
||||
|
||||
if (*p == '+' || *p == '-')
|
||||
p++;
|
||||
|
||||
while (isdigit (*p))
|
||||
p++;
|
||||
|
||||
if (strncmp (p, decimal_point, decimal_point_len) == 0) {
|
||||
*p = '.';
|
||||
decimal_len = strlen (p + decimal_point_len);
|
||||
memmove (p + 1, p + decimal_point_len, decimal_len);
|
||||
p[1 + decimal_len] = 0;
|
||||
|
||||
/* Remove trailing zeros and decimal point if possible. */
|
||||
for (p = p + decimal_len; *p == '0'; p--)
|
||||
*p = 0;
|
||||
|
||||
if (*p == '.') {
|
||||
*p = 0;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
LENGTH_MODIFIER_LONG = 0x100
|
||||
};
|
||||
|
||||
/* Here's a limited reimplementation of printf. The reason for doing
|
||||
* this is primarily to special case handling of doubles. We want
|
||||
* locale independent formatting of doubles and we want to trim
|
||||
* trailing zeros. This is handled by dtostr() above, and the code
|
||||
* below handles everything else by calling snprintf() to do the
|
||||
* formatting. This functionality is only for internal use and we
|
||||
* only implement the formats we actually use.
|
||||
*/
|
||||
void
|
||||
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
#define SINGLE_FMT_BUFFER_SIZE 32
|
||||
char buffer[512], single_fmt[SINGLE_FMT_BUFFER_SIZE];
|
||||
int single_fmt_length;
|
||||
char *p;
|
||||
const char *f, *start;
|
||||
int length_modifier, width;
|
||||
cairo_bool_t var_width;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
f = fmt;
|
||||
p = buffer;
|
||||
while (*f != '\0') {
|
||||
if (p == buffer + sizeof (buffer)) {
|
||||
_cairo_output_stream_write (stream, buffer, sizeof (buffer));
|
||||
p = buffer;
|
||||
}
|
||||
|
||||
if (*f != '%') {
|
||||
*p++ = *f++;
|
||||
continue;
|
||||
}
|
||||
|
||||
start = f;
|
||||
f++;
|
||||
|
||||
if (*f == '0')
|
||||
f++;
|
||||
|
||||
var_width = FALSE;
|
||||
if (*f == '*') {
|
||||
var_width = TRUE;
|
||||
f++;
|
||||
}
|
||||
|
||||
while (isdigit (*f))
|
||||
f++;
|
||||
|
||||
length_modifier = 0;
|
||||
if (*f == 'l') {
|
||||
length_modifier = LENGTH_MODIFIER_LONG;
|
||||
f++;
|
||||
}
|
||||
|
||||
/* The only format strings exist in the cairo implementation
|
||||
* itself. So there's an internal consistency problem if any
|
||||
* of them is larger than our format buffer size. */
|
||||
single_fmt_length = f - start + 1;
|
||||
assert (single_fmt_length + 1 <= SINGLE_FMT_BUFFER_SIZE);
|
||||
|
||||
/* Reuse the format string for this conversion. */
|
||||
memcpy (single_fmt, start, single_fmt_length);
|
||||
single_fmt[single_fmt_length] = '\0';
|
||||
|
||||
/* Flush contents of buffer before snprintf()'ing into it. */
|
||||
_cairo_output_stream_write (stream, buffer, p - buffer);
|
||||
|
||||
/* We group signed and unsigned together in this switch, the
|
||||
* only thing that matters here is the size of the arguments,
|
||||
* since we're just passing the data through to sprintf(). */
|
||||
switch (*f | length_modifier) {
|
||||
case '%':
|
||||
buffer[0] = *f;
|
||||
buffer[1] = 0;
|
||||
break;
|
||||
case 'd':
|
||||
case 'u':
|
||||
case 'o':
|
||||
case 'x':
|
||||
case 'X':
|
||||
if (var_width) {
|
||||
width = va_arg (ap, int);
|
||||
snprintf (buffer, sizeof buffer,
|
||||
single_fmt, width, va_arg (ap, int));
|
||||
} else {
|
||||
snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
|
||||
}
|
||||
break;
|
||||
case 'd' | LENGTH_MODIFIER_LONG:
|
||||
case 'u' | LENGTH_MODIFIER_LONG:
|
||||
case 'o' | LENGTH_MODIFIER_LONG:
|
||||
case 'x' | LENGTH_MODIFIER_LONG:
|
||||
case 'X' | LENGTH_MODIFIER_LONG:
|
||||
if (var_width) {
|
||||
width = va_arg (ap, int);
|
||||
snprintf (buffer, sizeof buffer,
|
||||
single_fmt, width, va_arg (ap, long int));
|
||||
} else {
|
||||
snprintf (buffer, sizeof buffer,
|
||||
single_fmt, va_arg (ap, long int));
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
snprintf (buffer, sizeof buffer,
|
||||
single_fmt, va_arg (ap, const char *));
|
||||
break;
|
||||
case 'f':
|
||||
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), FALSE);
|
||||
break;
|
||||
case 'g':
|
||||
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), TRUE);
|
||||
break;
|
||||
case 'c':
|
||||
buffer[0] = va_arg (ap, int);
|
||||
buffer[1] = 0;
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
p = buffer + strlen (buffer);
|
||||
f++;
|
||||
}
|
||||
|
||||
_cairo_output_stream_write (stream, buffer, p - buffer);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_printf (cairo_output_stream_t *stream,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
|
||||
_cairo_output_stream_vprintf (stream, fmt, ap);
|
||||
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
long
|
||||
_cairo_output_stream_get_position (cairo_output_stream_t *stream)
|
||||
{
|
||||
return stream->position;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_output_stream_get_status (cairo_output_stream_t *stream)
|
||||
{
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
/* Maybe this should be a configure time option, so embedded targets
|
||||
* don't have to pull in stdio. */
|
||||
|
||||
|
||||
typedef struct _stdio_stream {
|
||||
cairo_output_stream_t base;
|
||||
FILE *file;
|
||||
} stdio_stream_t;
|
||||
|
||||
static cairo_status_t
|
||||
stdio_write (cairo_output_stream_t *base,
|
||||
const unsigned char *data, unsigned int length)
|
||||
{
|
||||
stdio_stream_t *stream = (stdio_stream_t *) base;
|
||||
|
||||
if (fwrite (data, 1, length, stream->file) != length)
|
||||
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
stdio_flush (cairo_output_stream_t *base)
|
||||
{
|
||||
stdio_stream_t *stream = (stdio_stream_t *) base;
|
||||
|
||||
fflush (stream->file);
|
||||
|
||||
if (ferror (stream->file))
|
||||
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
else
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
stdio_close (cairo_output_stream_t *base)
|
||||
{
|
||||
cairo_status_t status;
|
||||
stdio_stream_t *stream = (stdio_stream_t *) base;
|
||||
|
||||
status = stdio_flush (base);
|
||||
|
||||
fclose (stream->file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (FILE *file)
|
||||
{
|
||||
stdio_stream_t *stream;
|
||||
|
||||
if (file == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
|
||||
}
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, stdio_write, stdio_flush);
|
||||
stream->file = file;
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_filename (const char *filename)
|
||||
{
|
||||
stdio_stream_t *stream;
|
||||
FILE *file;
|
||||
|
||||
if (filename == NULL)
|
||||
return _cairo_null_stream_create ();
|
||||
|
||||
file = fopen (filename, "wb");
|
||||
if (file == NULL) {
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
default:
|
||||
_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
|
||||
}
|
||||
}
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL) {
|
||||
fclose (file);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, stdio_write, stdio_close);
|
||||
stream->file = file;
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _memory_stream {
|
||||
cairo_output_stream_t base;
|
||||
cairo_array_t array;
|
||||
} memory_stream_t;
|
||||
|
||||
static cairo_status_t
|
||||
memory_write (cairo_output_stream_t *base,
|
||||
const unsigned char *data, unsigned int length)
|
||||
{
|
||||
memory_stream_t *stream = (memory_stream_t *) base;
|
||||
|
||||
return _cairo_array_append_multiple (&stream->array, data, length);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
memory_close (cairo_output_stream_t *base)
|
||||
{
|
||||
memory_stream_t *stream = (memory_stream_t *) base;
|
||||
|
||||
_cairo_array_fini (&stream->array);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_memory_stream_create (void)
|
||||
{
|
||||
memory_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, memory_write, memory_close);
|
||||
_cairo_array_init (&stream->array, 1);
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_memory_stream_copy (cairo_output_stream_t *base,
|
||||
cairo_output_stream_t *dest)
|
||||
{
|
||||
memory_stream_t *stream = (memory_stream_t *) base;
|
||||
|
||||
if (dest->status)
|
||||
return;
|
||||
|
||||
if (base->status) {
|
||||
dest->status = base->status;
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_output_stream_write (dest,
|
||||
_cairo_array_index (&stream->array, 0),
|
||||
_cairo_array_num_elements (&stream->array));
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_memory_stream_length (cairo_output_stream_t *base)
|
||||
{
|
||||
memory_stream_t *stream = (memory_stream_t *) base;
|
||||
|
||||
return _cairo_array_num_elements (&stream->array);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
null_write (cairo_output_stream_t *base,
|
||||
const unsigned char *data, unsigned int length)
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_null_stream_create (void)
|
||||
{
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (stream, null_write, NULL);
|
||||
|
||||
return stream;
|
||||
}
|
||||
167
uppdev/plugin/cairo/lib/cairo-paginated-private.h
Normal file
167
uppdev/plugin/cairo/lib/cairo-paginated-private.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PAGINATED_H
|
||||
#define CAIRO_PAGINATED_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
struct _cairo_paginated_surface_backend {
|
||||
/* Optional. Will be called once for each page.
|
||||
*
|
||||
* Note: With respect to the order of drawing operations as seen
|
||||
* by the target, this call will occur before any drawing
|
||||
* operations for the relevant page. However, with respect to the
|
||||
* function calls as made by the user, this call will be *after*
|
||||
* any drawing operations for the page, (that is, it will occur
|
||||
* during the user's call to cairo_show_page or cairo_copy_page).
|
||||
*/
|
||||
cairo_warn cairo_int_status_t
|
||||
(*start_page) (void *surface);
|
||||
|
||||
/* Required. Will be called twice for each page, once with an
|
||||
* argument of CAIRO_PAGINATED_MODE_ANALYZE and once with
|
||||
* CAIRO_PAGINATED_MODE_RENDER. See more details in the
|
||||
* documentation for _cairo_paginated_surface_create below.
|
||||
*/
|
||||
void
|
||||
(*set_paginated_mode) (void *surface,
|
||||
cairo_paginated_mode_t mode);
|
||||
|
||||
/* Optional. Specifies the smallest box that encloses all objects
|
||||
* on the page. Will be called at the end of the ANALYZE phase but
|
||||
* before the mode is changed to RENDER.
|
||||
*/
|
||||
cairo_warn cairo_int_status_t
|
||||
(*set_bounding_box) (void *surface,
|
||||
cairo_box_t *bbox);
|
||||
|
||||
/* Optional. Indicates whether the page requires fallback images.
|
||||
* Will be called at the end of the ANALYZE phase but before the
|
||||
* mode is changed to RENDER.
|
||||
*/
|
||||
cairo_warn cairo_int_status_t
|
||||
(*set_fallback_images_required) (void *surface,
|
||||
cairo_bool_t fallbacks_required);
|
||||
|
||||
cairo_bool_t
|
||||
(*supports_fine_grained_fallbacks) (void *surface);
|
||||
};
|
||||
|
||||
/* A #cairo_paginated_surface_t provides a very convenient wrapper that
|
||||
* is well-suited for doing the analysis common to most surfaces that
|
||||
* have paginated output, (that is, things directed at printers, or
|
||||
* for saving content in files such as PostScript or PDF files).
|
||||
*
|
||||
* To use the paginated surface, you'll first need to create your
|
||||
* 'real' surface using _cairo_surface_init() and the standard
|
||||
* #cairo_surface_backend_t. Then you also call
|
||||
* _cairo_paginated_surface_create which takes its own, much simpler,
|
||||
* #cairo_paginated_surface_backend_t. You are free to return the result
|
||||
* of _cairo_paginated_surface_create() from your public
|
||||
* cairo_<foo>_surface_create(). The paginated backend will be careful
|
||||
* to not let the user see that they really got a "wrapped"
|
||||
* surface. See test-paginated-surface.c for a fairly minimal example
|
||||
* of a paginated-using surface. That should be a reasonable example
|
||||
* to follow.
|
||||
*
|
||||
* What the paginated surface does is first save all drawing
|
||||
* operations for a page into a meta-surface. Then when the user calls
|
||||
* cairo_show_page(), the paginated surface performs the following
|
||||
* sequence of operations (using the backend functions passed to
|
||||
* cairo_paginated_surface_create()):
|
||||
*
|
||||
* 1. Calls start_page() (if not %NULL). At this point, it is appropriate
|
||||
* for the target to emit any page-specific header information into
|
||||
* its output.
|
||||
*
|
||||
* 2. Calls set_paginated_mode() with an argument of %CAIRO_PAGINATED_MODE_ANALYZE
|
||||
*
|
||||
* 3. Replays the meta-surface to the target surface, (with an
|
||||
* analysis surface inserted between which watches the return value
|
||||
* from each operation). This analysis stage is used to decide which
|
||||
* operations will require fallbacks.
|
||||
*
|
||||
* 4. Calls set_bounding_box() to provide the target surface with the
|
||||
* tight bounding box of the page.
|
||||
*
|
||||
* 5. Calls set_paginated_mode() with an argument of %CAIRO_PAGINATED_MODE_RENDER
|
||||
*
|
||||
* 6. Replays a subset of the meta-surface operations to the target surface
|
||||
*
|
||||
* 7. Calls set_paginated_mode() with an argument of %CAIRO_PAGINATED_MODE_FALLBACK
|
||||
*
|
||||
* 8. Replays the remaining operations to an image surface, sets an
|
||||
* appropriate clip on the target, then paints the resulting image
|
||||
* surface to the target.
|
||||
*
|
||||
* So, the target will see drawing operations during three separate
|
||||
* stages, (ANALYZE, RENDER and FALLBACK). During the ANALYZE phase
|
||||
* the target should not actually perform any rendering, (for example,
|
||||
* if performing output to a file, no output should be generated
|
||||
* during this stage). Instead the drawing functions simply need to
|
||||
* return %CAIRO_STATUS_SUCCESS or %CAIRO_INT_STATUS_UNSUPPORTED to
|
||||
* indicate whether rendering would be supported. And it should do
|
||||
* this as quickly as possible. The FALLBACK phase allows the surface
|
||||
* to distinguish fallback images from native rendering in case they
|
||||
* need to be handled as a special case.
|
||||
*
|
||||
* Note: The paginated surface layer assumes that the target surface
|
||||
* is "blank" by default at the beginning of each page, without any
|
||||
* need for an explicit erase operation, (as opposed to an image
|
||||
* surface, for example, which might have uninitialized content
|
||||
* originally). As such, it optimizes away CLEAR operations that
|
||||
* happen at the beginning of each page---the target surface will not
|
||||
* even see these operations.
|
||||
*/
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height,
|
||||
const cairo_paginated_surface_backend_t *backend);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_paginated_surface_get_target (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_paginated (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
#endif /* CAIRO_PAGINATED_H */
|
||||
72
uppdev/plugin/cairo/lib/cairo-paginated-surface-private.h
Normal file
72
uppdev/plugin/cairo/lib/cairo-paginated-surface-private.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PAGINATED_SURFACE_H
|
||||
#define CAIRO_PAGINATED_SURFACE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#include "cairo-surface-private.h"
|
||||
|
||||
typedef struct _cairo_paginated_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* The target surface to hold the final result. */
|
||||
cairo_surface_t *target;
|
||||
|
||||
cairo_content_t content;
|
||||
|
||||
/* XXX: These shouldn't actually exist. We inherit this ugliness
|
||||
* from _cairo_meta_surface_create. The width/height parameters
|
||||
* from that function also should not exist. The fix that will
|
||||
* allow us to remove all of these is to fix acquire_source_image
|
||||
* to pass an interest rectangle. */
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* Paginated-surface specific functions for the target */
|
||||
const cairo_paginated_surface_backend_t *backend;
|
||||
|
||||
/* A cairo_meta_surface to record all operations. To be replayed
|
||||
* against target, and also against image surface as necessary for
|
||||
* fallbacks. */
|
||||
cairo_surface_t *meta;
|
||||
|
||||
int page_num;
|
||||
cairo_bool_t page_is_blank;
|
||||
|
||||
} cairo_paginated_surface_t;
|
||||
|
||||
#endif /* CAIRO_PAGINATED_SURFACE_H */
|
||||
693
uppdev/plugin/cairo/lib/cairo-paginated-surface.c
Normal file
693
uppdev/plugin/cairo/lib/cairo-paginated-surface.c
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
* Copyright © 2007 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
/* The paginated surface layer exists to provide as much code sharing
|
||||
* as possible for the various paginated surface backends in cairo
|
||||
* (PostScript, PDF, etc.). See cairo-paginated-private.h for
|
||||
* more details on how it works and how to use it.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-paginated-private.h"
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
|
||||
static const cairo_surface_backend_t cairo_paginated_surface_backend;
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface);
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
return cairo_surface_create_similar (surface->target, content,
|
||||
width, height);
|
||||
}
|
||||
|
||||
/* XXX The integer width,height here should be doubles and all uses updated */
|
||||
cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height,
|
||||
const cairo_paginated_surface_backend_t *backend)
|
||||
{
|
||||
cairo_paginated_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
|
||||
surface = malloc (sizeof (cairo_paginated_surface_t));
|
||||
if (surface == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend,
|
||||
content);
|
||||
|
||||
/* Override surface->base.type with target's type so we don't leak
|
||||
* evidence of the paginated wrapper out to the user. */
|
||||
surface->base.type = cairo_surface_get_type (target);
|
||||
|
||||
surface->target = cairo_surface_reference (target);
|
||||
|
||||
surface->content = content;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
surface->backend = backend;
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (content, width, height);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (status)
|
||||
goto FAIL_CLEANUP_SURFACE;
|
||||
|
||||
surface->page_num = 1;
|
||||
surface->page_is_blank = TRUE;
|
||||
|
||||
return &surface->base;
|
||||
|
||||
FAIL_CLEANUP_SURFACE:
|
||||
cairo_surface_destroy (target);
|
||||
free (surface);
|
||||
FAIL:
|
||||
return _cairo_surface_create_in_error (status);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_surface_is_paginated (cairo_surface_t *surface)
|
||||
{
|
||||
return surface->backend == &cairo_paginated_surface_backend;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_paginated_surface_get_target (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_paginated_surface_t *paginated_surface;
|
||||
|
||||
assert (_cairo_surface_is_paginated (surface));
|
||||
|
||||
paginated_surface = (cairo_paginated_surface_t *) surface;
|
||||
|
||||
return paginated_surface->target;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *paginated_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
assert (_cairo_surface_is_paginated (surface));
|
||||
|
||||
paginated_surface = (cairo_paginated_surface_t *) surface;
|
||||
|
||||
paginated_surface->width = width;
|
||||
paginated_surface->height = height;
|
||||
|
||||
cairo_surface_destroy (paginated_surface->meta);
|
||||
paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content,
|
||||
width, height);
|
||||
status = cairo_surface_status (paginated_surface->meta);
|
||||
if (status)
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_paginated_surface_finish (void *abstract_surface)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (surface->page_is_blank == FALSE || surface->page_num == 1) {
|
||||
cairo_surface_show_page (abstract_surface);
|
||||
status = cairo_surface_status (abstract_surface);
|
||||
}
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_finish (surface->target);
|
||||
status = cairo_surface_status (surface->target);
|
||||
}
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_finish (surface->meta);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (surface->target);
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_create_image_surface (void *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
cairo_font_options_t options;
|
||||
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
width,
|
||||
height);
|
||||
|
||||
cairo_surface_get_font_options (&surface->base, &options);
|
||||
_cairo_surface_set_font_options (image, &options);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
status = _cairo_surface_get_extents (surface->target, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
status = _cairo_meta_surface_replay (surface->meta, image);
|
||||
if (status) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
}
|
||||
|
||||
*image_out = (cairo_image_surface_t*) image;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_paginated_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_paint_fallback_image (cairo_paginated_surface_t *surface,
|
||||
cairo_box_int_t *box)
|
||||
{
|
||||
double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution;
|
||||
double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution;
|
||||
cairo_matrix_t matrix;
|
||||
int x, y, width, height;
|
||||
cairo_status_t status;
|
||||
cairo_surface_t *image;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
x = box->p1.x;
|
||||
y = box->p1.y;
|
||||
width = box->p2.x - x;
|
||||
height = box->p2.y - y;
|
||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||
ceil (width * x_scale),
|
||||
ceil (height * y_scale));
|
||||
_cairo_surface_set_device_scale (image, x_scale, y_scale);
|
||||
/* set_device_offset just sets the x0/y0 components of the matrix;
|
||||
* so we have to do the scaling manually. */
|
||||
cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
|
||||
|
||||
status = _cairo_meta_surface_replay (surface->meta, image);
|
||||
if (status)
|
||||
goto CLEANUP_IMAGE;
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (image);
|
||||
cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale);
|
||||
cairo_pattern_set_matrix (pattern, &matrix);
|
||||
|
||||
status = _cairo_surface_paint (surface->target,
|
||||
CAIRO_OPERATOR_SOURCE,
|
||||
pattern);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
CLEANUP_IMAGE:
|
||||
cairo_surface_destroy (image);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_paint_page (cairo_paginated_surface_t *surface)
|
||||
{
|
||||
cairo_surface_t *analysis;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
|
||||
|
||||
if (surface->target->status)
|
||||
return surface->target->status;
|
||||
|
||||
analysis = _cairo_analysis_surface_create (surface->target,
|
||||
surface->width, surface->height);
|
||||
if (analysis->status)
|
||||
return _cairo_surface_set_error (surface->target, analysis->status);
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_ANALYZE);
|
||||
status = _cairo_meta_surface_replay_and_create_regions (surface->meta,
|
||||
analysis);
|
||||
if (status || analysis->status) {
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = analysis->status;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (surface->backend->set_bounding_box) {
|
||||
cairo_box_t bbox;
|
||||
|
||||
_cairo_analysis_surface_get_bounding_box (analysis, &bbox);
|
||||
status = surface->backend->set_bounding_box (surface->target, &bbox);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (surface->backend->set_fallback_images_required) {
|
||||
cairo_bool_t has_fallbacks = _cairo_analysis_surface_has_unsupported (analysis);
|
||||
|
||||
status = surface->backend->set_fallback_images_required (surface->target,
|
||||
has_fallbacks);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* Finer grained fallbacks are currently only supported for some
|
||||
* surface types */
|
||||
if (surface->backend->supports_fine_grained_fallbacks != NULL &&
|
||||
surface->backend->supports_fine_grained_fallbacks (surface->target))
|
||||
{
|
||||
has_supported = _cairo_analysis_surface_has_supported (analysis);
|
||||
has_page_fallback = FALSE;
|
||||
has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_cairo_analysis_surface_has_unsupported (analysis)) {
|
||||
has_supported = FALSE;
|
||||
has_page_fallback = TRUE;
|
||||
} else {
|
||||
has_supported = TRUE;
|
||||
has_page_fallback = FALSE;
|
||||
}
|
||||
has_finegrained_fallback = FALSE;
|
||||
}
|
||||
|
||||
if (has_supported) {
|
||||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_RENDER);
|
||||
|
||||
status = _cairo_meta_surface_replay_region (surface->meta,
|
||||
surface->target,
|
||||
CAIRO_META_REGION_NATIVE);
|
||||
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (has_page_fallback) {
|
||||
cairo_box_int_t box;
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_FALLBACK);
|
||||
|
||||
box.p1.x = 0;
|
||||
box.p1.y = 0;
|
||||
box.p2.x = surface->width;
|
||||
box.p2.y = surface->height;
|
||||
status = _paint_fallback_image (surface, &box);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (has_finegrained_fallback) {
|
||||
cairo_region_t *region;
|
||||
cairo_box_int_t *boxes;
|
||||
int num_boxes, i;
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_FALLBACK);
|
||||
|
||||
/* Reset clip region before drawing the fall back images */
|
||||
status = _cairo_surface_intersect_clip_path (surface->target,
|
||||
NULL,
|
||||
CAIRO_FILL_RULE_WINDING,
|
||||
CAIRO_GSTATE_TOLERANCE_DEFAULT,
|
||||
CAIRO_ANTIALIAS_DEFAULT);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
region = _cairo_analysis_surface_get_unsupported (analysis);
|
||||
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
status = _paint_fallback_image (surface, &boxes[i]);
|
||||
if (status) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
}
|
||||
|
||||
FAIL:
|
||||
cairo_surface_destroy (analysis);
|
||||
|
||||
return _cairo_surface_set_error (surface->target, status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_start_page (cairo_paginated_surface_t *surface)
|
||||
{
|
||||
if (surface->target->status)
|
||||
return surface->target->status;
|
||||
|
||||
if (! surface->backend->start_page)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_surface_set_error (surface->target,
|
||||
surface->backend->start_page (surface->target));
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_copy_page (void *abstract_surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
status = _start_page (surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _paint_page (surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
surface->page_num++;
|
||||
|
||||
/* XXX: It might make sense to add some suport here for calling
|
||||
* cairo_surface_copy_page on the target surface. It would be an
|
||||
* optimization for the output, but the interaction with image
|
||||
* fallbacks gets tricky. For now, we just let the target see a
|
||||
* show_page and we implement the copying by simply not destroying
|
||||
* the meta-surface. */
|
||||
|
||||
cairo_surface_show_page (surface->target);
|
||||
return cairo_surface_status (surface->target);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
status = _start_page (surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _paint_page (surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cairo_surface_show_page (surface->target);
|
||||
status = cairo_surface_status (surface->target);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (surface->content,
|
||||
surface->width,
|
||||
surface->height);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
surface->page_num++;
|
||||
surface->page_is_blank = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_intersect_clip_path (void *abstract_surface,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_intersect_clip_path (surface->meta,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_paginated_surface_get_font_options (void *abstract_surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
cairo_surface_get_font_options (surface->target, options);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_paint (surface->meta, op, source);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_mask (surface->meta, op, source, mask);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_stroke (surface->meta, op, source,
|
||||
path, style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_fill (surface->meta, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return cairo_surface_has_show_text_glyphs (surface->target);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_text_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
const cairo_text_cluster_t *clusters,
|
||||
int num_clusters,
|
||||
cairo_text_cluster_flags_t cluster_flags,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_int_status_t status;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
/* Since this is a "wrapping" surface, we're calling back into
|
||||
* _cairo_surface_show_text_glyphs from within a call to the same.
|
||||
* Since _cairo_surface_show_text_glyphs acquires a mutex, we release
|
||||
* and re-acquire the mutex around this nested call.
|
||||
*
|
||||
* Yes, this is ugly, but we consider it pragmatic as compared to
|
||||
* adding locking code to all 18 surface-backend-specific
|
||||
* show_glyphs functions, (which would get less testing and likely
|
||||
* lead to bugs).
|
||||
*/
|
||||
status = _cairo_surface_show_text_glyphs (surface->meta, op, source,
|
||||
utf8, utf8_len,
|
||||
glyphs, num_glyphs,
|
||||
clusters, num_clusters,
|
||||
cluster_flags,
|
||||
scaled_font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_snapshot (void *abstract_other)
|
||||
{
|
||||
cairo_paginated_surface_t *other = abstract_other;
|
||||
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
_cairo_paginated_surface_create_similar,
|
||||
_cairo_paginated_surface_finish,
|
||||
_cairo_paginated_surface_acquire_source_image,
|
||||
_cairo_paginated_surface_release_source_image,
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
_cairo_paginated_surface_copy_page,
|
||||
_cairo_paginated_surface_show_page,
|
||||
NULL, /* set_clip_region */
|
||||
_cairo_paginated_surface_intersect_clip_path,
|
||||
_cairo_paginated_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
_cairo_paginated_surface_get_font_options,
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
_cairo_paginated_surface_paint,
|
||||
_cairo_paginated_surface_mask,
|
||||
_cairo_paginated_surface_stroke,
|
||||
_cairo_paginated_surface_fill,
|
||||
NULL, /* show_glyphs */
|
||||
_cairo_paginated_surface_snapshot,
|
||||
NULL, /* is_similar */
|
||||
NULL, /* reset */
|
||||
NULL, /* fill_stroke */
|
||||
NULL, /* create_solid_pattern_surface */
|
||||
_cairo_paginated_surface_has_show_text_glyphs,
|
||||
_cairo_paginated_surface_show_text_glyphs
|
||||
};
|
||||
174
uppdev/plugin/cairo/lib/cairo-path-bounds.c
Normal file
174
uppdev/plugin/cairo/lib/cairo-path-bounds.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct cairo_path_bounder {
|
||||
cairo_point_t move_to_point;
|
||||
cairo_bool_t has_move_to_point;
|
||||
cairo_bool_t has_point;
|
||||
|
||||
cairo_fixed_t min_x;
|
||||
cairo_fixed_t min_y;
|
||||
cairo_fixed_t max_x;
|
||||
cairo_fixed_t max_y;
|
||||
} cairo_path_bounder_t;
|
||||
|
||||
static void
|
||||
_cairo_path_bounder_init (cairo_path_bounder_t *bounder);
|
||||
|
||||
static void
|
||||
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder);
|
||||
|
||||
static void
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_move_to (void *closure, cairo_point_t *point);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_line_to (void *closure, cairo_point_t *point);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_close_path (void *closure);
|
||||
|
||||
static void
|
||||
_cairo_path_bounder_init (cairo_path_bounder_t *bounder)
|
||||
{
|
||||
bounder->has_move_to_point = FALSE;
|
||||
bounder->has_point = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
|
||||
{
|
||||
bounder->has_move_to_point = FALSE;
|
||||
bounder->has_point = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point)
|
||||
{
|
||||
if (bounder->has_point) {
|
||||
if (point->x < bounder->min_x)
|
||||
bounder->min_x = point->x;
|
||||
|
||||
if (point->y < bounder->min_y)
|
||||
bounder->min_y = point->y;
|
||||
|
||||
if (point->x > bounder->max_x)
|
||||
bounder->max_x = point->x;
|
||||
|
||||
if (point->y > bounder->max_y)
|
||||
bounder->max_y = point->y;
|
||||
} else {
|
||||
bounder->min_x = point->x;
|
||||
bounder->min_y = point->y;
|
||||
bounder->max_x = point->x;
|
||||
bounder->max_y = point->y;
|
||||
|
||||
bounder->has_point = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cairo_path_bounder_t *bounder = closure;
|
||||
|
||||
bounder->move_to_point = *point;
|
||||
bounder->has_move_to_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cairo_path_bounder_t *bounder = closure;
|
||||
|
||||
if (bounder->has_move_to_point) {
|
||||
_cairo_path_bounder_add_point (bounder,
|
||||
&bounder->move_to_point);
|
||||
bounder->has_move_to_point = FALSE;
|
||||
}
|
||||
|
||||
_cairo_path_bounder_add_point (bounder, point);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_close_path (void *closure)
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2,
|
||||
double tolerance)
|
||||
{
|
||||
cairo_path_bounder_t bounder;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_path_bounder_init (&bounder);
|
||||
|
||||
status = _cairo_path_fixed_interpret_flat (path, CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_path_bounder_move_to,
|
||||
_cairo_path_bounder_line_to,
|
||||
_cairo_path_bounder_close_path,
|
||||
&bounder,
|
||||
tolerance);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS && bounder.has_point) {
|
||||
*x1 = _cairo_fixed_to_double (bounder.min_x);
|
||||
*y1 = _cairo_fixed_to_double (bounder.min_y);
|
||||
*x2 = _cairo_fixed_to_double (bounder.max_x);
|
||||
*y2 = _cairo_fixed_to_double (bounder.max_y);
|
||||
} else {
|
||||
*x1 = 0.0;
|
||||
*y1 = 0.0;
|
||||
*x2 = 0.0;
|
||||
*y2 = 0.0;
|
||||
}
|
||||
|
||||
_cairo_path_bounder_fini (&bounder);
|
||||
|
||||
return status;
|
||||
}
|
||||
239
uppdev/plugin/cairo/lib/cairo-path-fill.c
Normal file
239
uppdev/plugin/cairo/lib/cairo-path-fill.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
typedef struct cairo_filler {
|
||||
double tolerance;
|
||||
cairo_traps_t *traps;
|
||||
|
||||
cairo_point_t current_point;
|
||||
|
||||
cairo_polygon_t polygon;
|
||||
} cairo_filler_t;
|
||||
|
||||
static void
|
||||
_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps);
|
||||
|
||||
static void
|
||||
_cairo_filler_fini (cairo_filler_t *filler);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_move_to (void *closure, cairo_point_t *point);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_line_to (void *closure, cairo_point_t *point);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_curve_to (void *closure,
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_close_path (void *closure);
|
||||
|
||||
static void
|
||||
_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps)
|
||||
{
|
||||
filler->tolerance = tolerance;
|
||||
filler->traps = traps;
|
||||
|
||||
filler->current_point.x = 0;
|
||||
filler->current_point.y = 0;
|
||||
|
||||
_cairo_polygon_init (&filler->polygon);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_filler_fini (cairo_filler_t *filler)
|
||||
{
|
||||
_cairo_polygon_fini (&filler->polygon);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cairo_filler_t *filler = closure;
|
||||
cairo_polygon_t *polygon = &filler->polygon;
|
||||
|
||||
_cairo_polygon_close (polygon);
|
||||
_cairo_polygon_move_to (polygon, point);
|
||||
|
||||
filler->current_point = *point;
|
||||
|
||||
return _cairo_polygon_status (&filler->polygon);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cairo_filler_t *filler = closure;
|
||||
cairo_polygon_t *polygon = &filler->polygon;
|
||||
|
||||
_cairo_polygon_line_to (polygon, point);
|
||||
|
||||
filler->current_point = *point;
|
||||
|
||||
return _cairo_polygon_status (&filler->polygon);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_curve_to (void *closure,
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d)
|
||||
{
|
||||
int i;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_filler_t *filler = closure;
|
||||
cairo_polygon_t *polygon = &filler->polygon;
|
||||
cairo_spline_t spline;
|
||||
|
||||
status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);
|
||||
|
||||
if (status == CAIRO_INT_STATUS_DEGENERATE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_spline_decompose (&spline, filler->tolerance);
|
||||
if (status)
|
||||
goto CLEANUP_SPLINE;
|
||||
|
||||
for (i = 1; i < spline.num_points; i++)
|
||||
_cairo_polygon_line_to (polygon, &spline.points[i]);
|
||||
|
||||
CLEANUP_SPLINE:
|
||||
_cairo_spline_fini (&spline);
|
||||
|
||||
filler->current_point = *d;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_close_path (void *closure)
|
||||
{
|
||||
cairo_filler_t *filler = closure;
|
||||
cairo_polygon_t *polygon = &filler->polygon;
|
||||
|
||||
_cairo_polygon_close (polygon);
|
||||
|
||||
return _cairo_polygon_status (polygon);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_traps_t *traps);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_filler_t filler;
|
||||
|
||||
/* Before we do anything else, we use a special-case filler for
|
||||
* a device-axis aligned rectangle if possible. */
|
||||
status = _cairo_path_fixed_fill_rectangle (path, traps);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
_cairo_filler_init (&filler, tolerance, traps);
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_filler_move_to,
|
||||
_cairo_filler_line_to,
|
||||
_cairo_filler_curve_to,
|
||||
_cairo_filler_close_path,
|
||||
&filler);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
_cairo_polygon_close (&filler.polygon);
|
||||
status = _cairo_polygon_status (&filler.polygon);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
status = _cairo_bentley_ottmann_tessellate_polygon (filler.traps,
|
||||
&filler.polygon,
|
||||
fill_rule);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
BAIL:
|
||||
_cairo_filler_fini (&filler);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* This special-case filler supports only a path that describes a
|
||||
* device-axis aligned rectangle. It exists to avoid the overhead of
|
||||
* the general tessellator when drawing very common rectangles.
|
||||
*
|
||||
* If the path described anything but a device-axis aligned rectangle,
|
||||
* this function will return %CAIRO_INT_STATUS_UNSUPPORTED.
|
||||
*/
|
||||
static cairo_int_status_t
|
||||
_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
if (_cairo_path_fixed_is_box (path, NULL)) {
|
||||
cairo_point_t *p = path->buf_head.base.points;
|
||||
cairo_point_t *top_left, *bot_right;
|
||||
|
||||
top_left = &p[0];
|
||||
bot_right = &p[2];
|
||||
if (top_left->x > bot_right->x || top_left->y > bot_right->y) {
|
||||
int n;
|
||||
|
||||
/* not a simple cairo_rectangle() */
|
||||
for (n = 0; n < 4; n++) {
|
||||
if (p[n].x <= top_left->x && p[n].y <= top_left->y)
|
||||
top_left = &p[n];
|
||||
if (p[n].x >= bot_right->x && p[n].y >= bot_right->y)
|
||||
bot_right = &p[n];
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_traps_tessellate_rectangle (traps, top_left, bot_right);
|
||||
}
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
80
uppdev/plugin/cairo/lib/cairo-path-fixed-private.h
Normal file
80
uppdev/plugin/cairo/lib/cairo-path-fixed-private.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PATH_FIXED_PRIVATE_H
|
||||
#define CAIRO_PATH_FIXED_PRIVATE_H
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
enum cairo_path_op {
|
||||
CAIRO_PATH_OP_MOVE_TO = 0,
|
||||
CAIRO_PATH_OP_LINE_TO = 1,
|
||||
CAIRO_PATH_OP_CURVE_TO = 2,
|
||||
CAIRO_PATH_OP_CLOSE_PATH = 3
|
||||
};
|
||||
/* we want to make sure a single byte is used for thie enum */
|
||||
typedef char cairo_path_op_t;
|
||||
|
||||
/* make _cairo_path_fixed fit a 512 bytes. about 50 items */
|
||||
#define CAIRO_PATH_BUF_SIZE ((512 - 4 * sizeof (void*) - sizeof (cairo_path_buf_t)) \
|
||||
/ (2 * sizeof (cairo_point_t) + sizeof (cairo_path_op_t)))
|
||||
|
||||
typedef struct _cairo_path_buf {
|
||||
struct _cairo_path_buf *next, *prev;
|
||||
int buf_size;
|
||||
int num_ops;
|
||||
int num_points;
|
||||
|
||||
cairo_path_op_t *op;
|
||||
cairo_point_t *points;
|
||||
} cairo_path_buf_t;
|
||||
typedef struct _cairo_path_buf_fixed {
|
||||
cairo_path_buf_t base;
|
||||
|
||||
cairo_path_op_t op[CAIRO_PATH_BUF_SIZE];
|
||||
cairo_point_t points[2 * CAIRO_PATH_BUF_SIZE];
|
||||
} cairo_path_buf_fixed_t;
|
||||
|
||||
struct _cairo_path_fixed {
|
||||
cairo_point_t last_move_point;
|
||||
cairo_point_t current_point;
|
||||
unsigned int has_current_point : 1;
|
||||
unsigned int has_curve_to : 1;
|
||||
|
||||
cairo_path_buf_t *buf_tail;
|
||||
cairo_path_buf_fixed_t buf_head;
|
||||
};
|
||||
|
||||
#endif /* CAIRO_PATH_FIXED_PRIVATE_H */
|
||||
896
uppdev/plugin/cairo/lib/cairo-path-fixed.c
Normal file
896
uppdev/plugin/cairo/lib/cairo-path-fixed.c
Normal file
|
|
@ -0,0 +1,896 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
/* private functions */
|
||||
static cairo_status_t
|
||||
_cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_path_op_t op,
|
||||
cairo_point_t *points,
|
||||
int num_points);
|
||||
|
||||
static void
|
||||
_cairo_path_fixed_add_buf (cairo_path_fixed_t *path,
|
||||
cairo_path_buf_t *buf);
|
||||
|
||||
static cairo_path_buf_t *
|
||||
_cairo_path_buf_create (int buf_size);
|
||||
|
||||
static void
|
||||
_cairo_path_buf_destroy (cairo_path_buf_t *buf);
|
||||
|
||||
static void
|
||||
_cairo_path_buf_add_op (cairo_path_buf_t *buf,
|
||||
cairo_path_op_t op);
|
||||
|
||||
static void
|
||||
_cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
cairo_point_t *points,
|
||||
int num_points);
|
||||
|
||||
void
|
||||
_cairo_path_fixed_init (cairo_path_fixed_t *path)
|
||||
{
|
||||
path->buf_head.base.next = NULL;
|
||||
path->buf_head.base.prev = NULL;
|
||||
path->buf_tail = &path->buf_head.base;
|
||||
|
||||
path->buf_head.base.num_ops = 0;
|
||||
path->buf_head.base.num_points = 0;
|
||||
path->buf_head.base.buf_size = CAIRO_PATH_BUF_SIZE;
|
||||
path->buf_head.base.op = path->buf_head.op;
|
||||
path->buf_head.base.points = path->buf_head.points;
|
||||
|
||||
path->current_point.x = 0;
|
||||
path->current_point.y = 0;
|
||||
path->has_current_point = FALSE;
|
||||
path->has_curve_to = FALSE;
|
||||
path->last_move_point = path->current_point;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||
cairo_path_fixed_t *other)
|
||||
{
|
||||
cairo_path_buf_t *buf, *other_buf;
|
||||
unsigned int num_points, num_ops, buf_size;
|
||||
|
||||
_cairo_path_fixed_init (path);
|
||||
|
||||
path->current_point = other->current_point;
|
||||
path->has_current_point = other->has_current_point;
|
||||
path->has_curve_to = other->has_curve_to;
|
||||
path->last_move_point = other->last_move_point;
|
||||
|
||||
path->buf_head.base.num_ops = other->buf_head.base.num_ops;
|
||||
path->buf_head.base.num_points = other->buf_head.base.num_points;
|
||||
path->buf_head.base.buf_size = other->buf_head.base.buf_size;
|
||||
memcpy (path->buf_head.op, other->buf_head.base.op,
|
||||
other->buf_head.base.num_ops * sizeof (other->buf_head.op[0]));
|
||||
memcpy (path->buf_head.points, other->buf_head.points,
|
||||
other->buf_head.base.num_points * sizeof (other->buf_head.points[0]));
|
||||
|
||||
num_points = num_ops = 0;
|
||||
for (other_buf = other->buf_head.base.next;
|
||||
other_buf != NULL;
|
||||
other_buf = other_buf->next)
|
||||
{
|
||||
num_ops += other_buf->num_ops;
|
||||
num_points += other_buf->num_points;
|
||||
}
|
||||
|
||||
buf_size = MAX (num_ops, (num_points + 1) / 2);
|
||||
if (buf_size) {
|
||||
buf = _cairo_path_buf_create (buf_size);
|
||||
if (buf == NULL) {
|
||||
_cairo_path_fixed_fini (path);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (other_buf = other->buf_head.base.next;
|
||||
other_buf != NULL;
|
||||
other_buf = other_buf->next)
|
||||
{
|
||||
memcpy (buf->op + buf->num_ops, other_buf->op,
|
||||
other_buf->num_ops * sizeof (buf->op[0]));
|
||||
buf->num_ops += other_buf->num_ops;
|
||||
|
||||
memcpy (buf->points + buf->num_points, other_buf->points,
|
||||
other_buf->num_points * sizeof (buf->points[0]));
|
||||
buf->num_points += other_buf->num_points;
|
||||
}
|
||||
|
||||
_cairo_path_fixed_add_buf (path, buf);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_path_fixed_t *
|
||||
_cairo_path_fixed_create (void)
|
||||
{
|
||||
cairo_path_fixed_t *path;
|
||||
|
||||
path = malloc (sizeof (cairo_path_fixed_t));
|
||||
if (!path) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_cairo_path_fixed_init (path);
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_fini (cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
buf = path->buf_head.base.next;
|
||||
while (buf) {
|
||||
cairo_path_buf_t *this = buf;
|
||||
buf = buf->next;
|
||||
_cairo_path_buf_destroy (this);
|
||||
}
|
||||
path->buf_head.base.next = NULL;
|
||||
path->buf_head.base.prev = NULL;
|
||||
path->buf_tail = &path->buf_head.base;
|
||||
path->buf_head.base.num_ops = 0;
|
||||
path->buf_head.base.num_points = 0;
|
||||
|
||||
path->has_current_point = FALSE;
|
||||
path->has_curve_to = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_destroy (cairo_path_fixed_t *path)
|
||||
{
|
||||
_cairo_path_fixed_fini (path);
|
||||
free (path);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x,
|
||||
cairo_fixed_t y)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_point_t point;
|
||||
|
||||
point.x = x;
|
||||
point.y = y;
|
||||
|
||||
/* If the previous op was also a MOVE_TO, then just change its
|
||||
* point rather than adding a new op. */
|
||||
if (path->buf_tail && path->buf_tail->num_ops &&
|
||||
path->buf_tail->op[path->buf_tail->num_ops - 1] == CAIRO_PATH_OP_MOVE_TO)
|
||||
{
|
||||
cairo_point_t *last_move_to_point;
|
||||
last_move_to_point = &path->buf_tail->points[path->buf_tail->num_points - 1];
|
||||
*last_move_to_point = point;
|
||||
} else {
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = TRUE;
|
||||
path->last_move_point = path->current_point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path)
|
||||
{
|
||||
path->has_current_point = FALSE;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
cairo_fixed_t dy)
|
||||
{
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
y = path->current_point.y + dy;
|
||||
|
||||
return _cairo_path_fixed_move_to (path, x, y);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x,
|
||||
cairo_fixed_t y)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_point_t point;
|
||||
|
||||
point.x = x;
|
||||
point.y = y;
|
||||
|
||||
/* When there is not yet a current point, the line_to operation
|
||||
* becomes a move_to instead. Note: We have to do this by
|
||||
* explicitly calling into _cairo_path_fixed_line_to to ensure
|
||||
* that the last_move_point state is updated properly.
|
||||
*/
|
||||
if (! path->has_current_point)
|
||||
status = _cairo_path_fixed_move_to (path, point.x, point.y);
|
||||
else
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
cairo_fixed_t dy)
|
||||
{
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
y = path->current_point.y + dy;
|
||||
|
||||
return _cairo_path_fixed_line_to (path, x, y);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x0, cairo_fixed_t y0,
|
||||
cairo_fixed_t x1, cairo_fixed_t y1,
|
||||
cairo_fixed_t x2, cairo_fixed_t y2)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_point_t point[3];
|
||||
|
||||
point[0].x = x0; point[0].y = y0;
|
||||
point[1].x = x1; point[1].y = y1;
|
||||
point[2].x = x2; point[2].y = y2;
|
||||
|
||||
if (! path->has_current_point) {
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO,
|
||||
&point[0], 1);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point = point[2];
|
||||
path->has_current_point = TRUE;
|
||||
path->has_curve_to = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx0, cairo_fixed_t dy0,
|
||||
cairo_fixed_t dx1, cairo_fixed_t dy1,
|
||||
cairo_fixed_t dx2, cairo_fixed_t dy2)
|
||||
{
|
||||
cairo_fixed_t x0, y0;
|
||||
cairo_fixed_t x1, y1;
|
||||
cairo_fixed_t x2, y2;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
x0 = path->current_point.x + dx0;
|
||||
y0 = path->current_point.y + dy0;
|
||||
|
||||
x1 = path->current_point.x + dx1;
|
||||
y1 = path->current_point.y + dy1;
|
||||
|
||||
x2 = path->current_point.x + dx2;
|
||||
y2 = path->current_point.y + dy2;
|
||||
|
||||
return _cairo_path_fixed_curve_to (path,
|
||||
x0, y0,
|
||||
x1, y1,
|
||||
x2, y2);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_close_path (cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CLOSE_PATH, NULL, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_path_fixed_move_to (path,
|
||||
path->last_move_point.x,
|
||||
path->last_move_point.y);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_get_current_point (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t *x,
|
||||
cairo_fixed_t *y)
|
||||
{
|
||||
if (! path->has_current_point)
|
||||
return FALSE;
|
||||
|
||||
*x = path->current_point.x;
|
||||
*y = path->current_point.y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_path_op_t op,
|
||||
cairo_point_t *points,
|
||||
int num_points)
|
||||
{
|
||||
cairo_path_buf_t *buf = path->buf_tail;
|
||||
|
||||
if (buf->num_ops + 1 > buf->buf_size ||
|
||||
buf->num_points + num_points > 2 * buf->buf_size)
|
||||
{
|
||||
buf = _cairo_path_buf_create (buf->buf_size * 2);
|
||||
if (buf == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_path_fixed_add_buf (path, buf);
|
||||
}
|
||||
|
||||
_cairo_path_buf_add_op (buf, op);
|
||||
_cairo_path_buf_add_points (buf, points, num_points);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_fixed_add_buf (cairo_path_fixed_t *path,
|
||||
cairo_path_buf_t *buf)
|
||||
{
|
||||
buf->next = NULL;
|
||||
buf->prev = path->buf_tail;
|
||||
|
||||
path->buf_tail->next = buf;
|
||||
path->buf_tail = buf;
|
||||
}
|
||||
|
||||
static cairo_path_buf_t *
|
||||
_cairo_path_buf_create (int buf_size)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
/* adjust buf_size to ensure that buf->points is naturally aligned */
|
||||
buf_size += sizeof (double)
|
||||
- ((buf_size + sizeof (cairo_path_buf_t)) & (sizeof (double)-1));
|
||||
buf = _cairo_malloc_ab_plus_c (buf_size,
|
||||
sizeof (cairo_path_op_t) +
|
||||
2 * sizeof (cairo_point_t),
|
||||
sizeof (cairo_path_buf_t));
|
||||
if (buf) {
|
||||
buf->next = NULL;
|
||||
buf->prev = NULL;
|
||||
buf->num_ops = 0;
|
||||
buf->num_points = 0;
|
||||
buf->buf_size = buf_size;
|
||||
|
||||
buf->op = (cairo_path_op_t *) (buf + 1);
|
||||
buf->points = (cairo_point_t *) (buf->op + buf_size);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_buf_destroy (cairo_path_buf_t *buf)
|
||||
{
|
||||
free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_buf_add_op (cairo_path_buf_t *buf,
|
||||
cairo_path_op_t op)
|
||||
{
|
||||
buf->op[buf->num_ops++] = op;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
cairo_point_t *points,
|
||||
int num_points)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_points; i++) {
|
||||
buf->points[buf->num_points++] = points[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int const num_args[] =
|
||||
{
|
||||
1, /* cairo_path_move_to */
|
||||
1, /* cairo_path_op_line_to */
|
||||
3, /* cairo_path_op_curve_to */
|
||||
0, /* cairo_path_op_close_path */
|
||||
};
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
|
||||
cairo_direction_t dir,
|
||||
cairo_path_fixed_move_to_func_t *move_to,
|
||||
cairo_path_fixed_line_to_func_t *line_to,
|
||||
cairo_path_fixed_curve_to_func_t *curve_to,
|
||||
cairo_path_fixed_close_path_func_t *close_path,
|
||||
void *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const cairo_path_buf_t *buf;
|
||||
cairo_path_op_t op;
|
||||
cairo_bool_t forward = (dir == CAIRO_DIRECTION_FORWARD);
|
||||
int step = forward ? 1 : -1;
|
||||
|
||||
for (buf = forward ? &path->buf_head.base : path->buf_tail;
|
||||
buf;
|
||||
buf = forward ? buf->next : buf->prev)
|
||||
{
|
||||
cairo_point_t *points;
|
||||
int start, stop, i;
|
||||
if (forward) {
|
||||
start = 0;
|
||||
stop = buf->num_ops;
|
||||
points = buf->points;
|
||||
} else {
|
||||
start = buf->num_ops - 1;
|
||||
stop = -1;
|
||||
points = buf->points + buf->num_points;
|
||||
}
|
||||
|
||||
for (i=start; i != stop; i += step) {
|
||||
op = buf->op[i];
|
||||
|
||||
if (! forward) {
|
||||
points -= num_args[(int) op];
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case CAIRO_PATH_OP_MOVE_TO:
|
||||
status = (*move_to) (closure, &points[0]);
|
||||
break;
|
||||
case CAIRO_PATH_OP_LINE_TO:
|
||||
status = (*line_to) (closure, &points[0]);
|
||||
break;
|
||||
case CAIRO_PATH_OP_CURVE_TO:
|
||||
status = (*curve_to) (closure, &points[0], &points[1], &points[2]);
|
||||
break;
|
||||
case CAIRO_PATH_OP_CLOSE_PATH:
|
||||
default:
|
||||
status = (*close_path) (closure);
|
||||
break;
|
||||
}
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (forward) {
|
||||
points += num_args[(int) op];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_append_move_to (void *closure,
|
||||
cairo_point_t *point)
|
||||
{
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_move_to (path, point->x, point->y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_append_line_to (void *closure,
|
||||
cairo_point_t *point)
|
||||
{
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_line_to (path, point->x, point->y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_append_curve_to (void *closure,
|
||||
cairo_point_t *p0,
|
||||
cairo_point_t *p1,
|
||||
cairo_point_t *p2)
|
||||
{
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_curve_to (path, p0->x, p0->y, p1->x, p1->y, p2->x, p2->y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_append_close_path (void *closure)
|
||||
{
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_close_path (path);
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_append (cairo_path_fixed_t *path,
|
||||
const cairo_path_fixed_t *other,
|
||||
cairo_direction_t dir)
|
||||
{
|
||||
return _cairo_path_fixed_interpret (other, dir,
|
||||
_append_move_to,
|
||||
_append_line_to,
|
||||
_append_curve_to,
|
||||
_append_close_path,
|
||||
path);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t offx,
|
||||
cairo_fixed_t offy,
|
||||
cairo_fixed_t scalex,
|
||||
cairo_fixed_t scaley)
|
||||
{
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
int i;
|
||||
|
||||
while (buf) {
|
||||
for (i = 0; i < buf->num_points; i++) {
|
||||
if (scalex != CAIRO_FIXED_ONE)
|
||||
buf->points[i].x = _cairo_fixed_mul (buf->points[i].x, scalex);
|
||||
buf->points[i].x += offx;
|
||||
|
||||
if (scaley != CAIRO_FIXED_ONE)
|
||||
buf->points[i].y = _cairo_fixed_mul (buf->points[i].y, scaley);
|
||||
buf->points[i].y += offy;
|
||||
}
|
||||
|
||||
buf = buf->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_path_fixed_transform:
|
||||
* @path: a #cairo_path_fixed_t to be transformed
|
||||
* @matrix: a #cairo_matrix_t
|
||||
*
|
||||
* Transform the fixed-point path according to the given matrix.
|
||||
* There is a fast path for the case where @matrix has no rotation
|
||||
* or shear.
|
||||
**/
|
||||
void
|
||||
_cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||
cairo_matrix_t *matrix)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
int i;
|
||||
double dx, dy;
|
||||
|
||||
if (matrix->yx == 0.0 && matrix->xy == 0.0) {
|
||||
/* Fast path for the common case of scale+transform */
|
||||
_cairo_path_fixed_offset_and_scale (path,
|
||||
_cairo_fixed_from_double (matrix->x0),
|
||||
_cairo_fixed_from_double (matrix->y0),
|
||||
_cairo_fixed_from_double (matrix->xx),
|
||||
_cairo_fixed_from_double (matrix->yy));
|
||||
return;
|
||||
}
|
||||
|
||||
buf = &path->buf_head.base;
|
||||
while (buf) {
|
||||
for (i = 0; i < buf->num_points; i++) {
|
||||
dx = _cairo_fixed_to_double (buf->points[i].x);
|
||||
dy = _cairo_fixed_to_double (buf->points[i].y);
|
||||
|
||||
cairo_matrix_transform_point (matrix, &dx, &dy);
|
||||
|
||||
buf->points[i].x = _cairo_fixed_from_double (dx);
|
||||
buf->points[i].y = _cairo_fixed_from_double (dy);
|
||||
}
|
||||
|
||||
buf = buf->next;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
|
||||
cairo_path_fixed_t *other)
|
||||
{
|
||||
cairo_path_buf_t *path_buf, *other_buf;
|
||||
|
||||
if (path->current_point.x != other->current_point.x ||
|
||||
path->current_point.y != other->current_point.y ||
|
||||
path->has_current_point != other->has_current_point ||
|
||||
path->has_curve_to != other->has_curve_to ||
|
||||
path->last_move_point.x != other->last_move_point.x ||
|
||||
path->last_move_point.y != other->last_move_point.y)
|
||||
return FALSE;
|
||||
|
||||
other_buf = &other->buf_head.base;
|
||||
for (path_buf = &path->buf_head.base;
|
||||
path_buf != NULL;
|
||||
path_buf = path_buf->next)
|
||||
{
|
||||
if (other_buf == NULL ||
|
||||
path_buf->num_ops != other_buf->num_ops ||
|
||||
path_buf->num_points != other_buf->num_points ||
|
||||
memcmp (path_buf->op, other_buf->op,
|
||||
sizeof (cairo_path_op_t) * path_buf->num_ops) != 0 ||
|
||||
memcmp (path_buf->points, other_buf->points,
|
||||
sizeof (cairo_point_t) * path_buf->num_points) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
other_buf = other_buf->next;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Closure for path flattening */
|
||||
typedef struct cairo_path_flattener {
|
||||
double tolerance;
|
||||
cairo_point_t current_point;
|
||||
cairo_path_fixed_move_to_func_t *move_to;
|
||||
cairo_path_fixed_line_to_func_t *line_to;
|
||||
cairo_path_fixed_close_path_func_t *close_path;
|
||||
void *closure;
|
||||
} cpf_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cpf_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cpf_t *cpf = closure;
|
||||
|
||||
cpf->current_point = *point;
|
||||
|
||||
return cpf->move_to (cpf->closure, point);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpf_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cpf_t *cpf = closure;
|
||||
|
||||
cpf->current_point = *point;
|
||||
|
||||
return cpf->line_to (cpf->closure, point);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpf_curve_to (void *closure,
|
||||
cairo_point_t *p1,
|
||||
cairo_point_t *p2,
|
||||
cairo_point_t *p3)
|
||||
{
|
||||
cpf_t *cpf = closure;
|
||||
cairo_status_t status;
|
||||
cairo_spline_t spline;
|
||||
int i;
|
||||
|
||||
cairo_point_t *p0 = &cpf->current_point;
|
||||
|
||||
status = _cairo_spline_init (&spline, p0, p1, p2, p3);
|
||||
if (status == CAIRO_INT_STATUS_DEGENERATE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_spline_decompose (&spline, cpf->tolerance);
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
for (i=1; i < spline.num_points; i++) {
|
||||
status = cpf->line_to (cpf->closure, &spline.points[i]);
|
||||
if (status)
|
||||
goto out;
|
||||
}
|
||||
|
||||
cpf->current_point = *p3;
|
||||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
out:
|
||||
_cairo_spline_fini (&spline);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpf_close_path (void *closure)
|
||||
{
|
||||
cpf_t *cpf = closure;
|
||||
|
||||
return cpf->close_path (cpf->closure);
|
||||
}
|
||||
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
|
||||
cairo_direction_t dir,
|
||||
cairo_path_fixed_move_to_func_t *move_to,
|
||||
cairo_path_fixed_line_to_func_t *line_to,
|
||||
cairo_path_fixed_close_path_func_t *close_path,
|
||||
void *closure,
|
||||
double tolerance)
|
||||
{
|
||||
cpf_t flattener;
|
||||
|
||||
flattener.tolerance = tolerance;
|
||||
flattener.move_to = move_to;
|
||||
flattener.line_to = line_to;
|
||||
flattener.close_path = close_path;
|
||||
flattener.closure = closure;
|
||||
return _cairo_path_fixed_interpret (path, dir,
|
||||
_cpf_move_to,
|
||||
_cpf_line_to,
|
||||
_cpf_curve_to,
|
||||
_cpf_close_path,
|
||||
&flattener);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_is_empty (cairo_path_fixed_t *path)
|
||||
{
|
||||
if (path->buf_head.base.num_ops == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given path contains a single rectangle.
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box)
|
||||
{
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
|
||||
/* We can't have more than one buf for this check */
|
||||
if (buf->next != NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Do we have the right number of ops? */
|
||||
if (buf->num_ops != 5 && buf->num_ops != 6)
|
||||
return FALSE;
|
||||
|
||||
/* Check whether the ops are those that would be used for a rectangle */
|
||||
if (buf->op[0] != CAIRO_PATH_OP_MOVE_TO ||
|
||||
buf->op[1] != CAIRO_PATH_OP_LINE_TO ||
|
||||
buf->op[2] != CAIRO_PATH_OP_LINE_TO ||
|
||||
buf->op[3] != CAIRO_PATH_OP_LINE_TO)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now, there are choices. The rectangle might end with a LINE_TO
|
||||
* (to the original point), but this isn't required. If it
|
||||
* doesn't, then it must end with a CLOSE_PATH. */
|
||||
if (buf->op[4] == CAIRO_PATH_OP_LINE_TO) {
|
||||
if (buf->points[4].x != buf->points[0].x ||
|
||||
buf->points[4].y != buf->points[0].y)
|
||||
return FALSE;
|
||||
} else if (buf->op[4] != CAIRO_PATH_OP_CLOSE_PATH) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (buf->num_ops == 6) {
|
||||
/* A trailing CLOSE_PATH or MOVE_TO is ok */
|
||||
if (buf->op[5] != CAIRO_PATH_OP_MOVE_TO &&
|
||||
buf->op[5] != CAIRO_PATH_OP_CLOSE_PATH)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ok, we may have a box, if the points line up */
|
||||
if (buf->points[0].y == buf->points[1].y &&
|
||||
buf->points[1].x == buf->points[2].x &&
|
||||
buf->points[2].y == buf->points[3].y &&
|
||||
buf->points[3].x == buf->points[0].x)
|
||||
{
|
||||
if (box) {
|
||||
box->p1 = buf->points[0];
|
||||
box->p2 = buf->points[2];
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (buf->points[0].x == buf->points[1].x &&
|
||||
buf->points[1].y == buf->points[2].y &&
|
||||
buf->points[2].x == buf->points[3].x &&
|
||||
buf->points[3].y == buf->points[0].y)
|
||||
{
|
||||
if (box) {
|
||||
box->p1 = buf->points[0];
|
||||
box->p2 = buf->points[2];
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the given path contains a single rectangle
|
||||
* that is logically equivalent to:
|
||||
* <informalexample><programlisting>
|
||||
* cairo_move_to (cr, x, y);
|
||||
* cairo_rel_line_to (cr, width, 0);
|
||||
* cairo_rel_line_to (cr, 0, height);
|
||||
* cairo_rel_line_to (cr, -width, 0);
|
||||
* cairo_close_path (cr);
|
||||
* </programlisting></informalexample>
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box)
|
||||
{
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
|
||||
if (!_cairo_path_fixed_is_box (path, box))
|
||||
return FALSE;
|
||||
|
||||
if (buf->points[0].y == buf->points[1].y)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
57
uppdev/plugin/cairo/lib/cairo-path-private.h
Normal file
57
uppdev/plugin/cairo/lib/cairo-path-private.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PATH_PRIVATE_H
|
||||
#define CAIRO_PATH_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
cairo_private cairo_path_t *
|
||||
_cairo_path_create (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_path_t *
|
||||
_cairo_path_create_flat (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_path_t *
|
||||
_cairo_path_create_in_error (cairo_status_t status);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_append_to_context (const cairo_path_t *path,
|
||||
cairo_t *cr);
|
||||
|
||||
#endif /* CAIRO_PATH_DATA_PRIVATE_H */
|
||||
1522
uppdev/plugin/cairo/lib/cairo-path-stroke.c
Normal file
1522
uppdev/plugin/cairo/lib/cairo-path-stroke.c
Normal file
File diff suppressed because it is too large
Load diff
482
uppdev/plugin/cairo/lib/cairo-path.c
Normal file
482
uppdev/plugin/cairo/lib/cairo-path.c
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-path-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
static const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
|
||||
|
||||
/* Closure for path interpretation. */
|
||||
typedef struct cairo_path_count {
|
||||
int count;
|
||||
cairo_point_t current_point;
|
||||
} cpc_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cpc_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cpc_t *cpc = closure;
|
||||
|
||||
cpc->count += 2;
|
||||
|
||||
cpc->current_point = *point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpc_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cpc_t *cpc = closure;
|
||||
|
||||
cpc->count += 2;
|
||||
|
||||
cpc->current_point = *point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpc_curve_to (void *closure,
|
||||
cairo_point_t *p1,
|
||||
cairo_point_t *p2,
|
||||
cairo_point_t *p3)
|
||||
{
|
||||
cpc_t *cpc = closure;
|
||||
|
||||
cpc->count += 4;
|
||||
|
||||
cpc->current_point = *p3;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpc_close_path (void *closure)
|
||||
{
|
||||
cpc_t *cpc = closure;
|
||||
|
||||
cpc->count += 1;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_path_count (cairo_path_t *path,
|
||||
cairo_path_fixed_t *path_fixed,
|
||||
double tolerance,
|
||||
cairo_bool_t flatten)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cpc_t cpc;
|
||||
|
||||
cpc.count = 0;
|
||||
cpc.current_point.x = 0;
|
||||
cpc.current_point.y = 0;
|
||||
|
||||
if (flatten) {
|
||||
status = _cairo_path_fixed_interpret_flat (path_fixed,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cpc_move_to,
|
||||
_cpc_line_to,
|
||||
_cpc_close_path,
|
||||
&cpc,
|
||||
tolerance);
|
||||
} else {
|
||||
status = _cairo_path_fixed_interpret (path_fixed,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cpc_move_to,
|
||||
_cpc_line_to,
|
||||
_cpc_curve_to,
|
||||
_cpc_close_path,
|
||||
&cpc);
|
||||
}
|
||||
|
||||
if (status)
|
||||
return -1;
|
||||
|
||||
return cpc.count;
|
||||
}
|
||||
|
||||
/* Closure for path interpretation. */
|
||||
typedef struct cairo_path_populate {
|
||||
cairo_path_data_t *data;
|
||||
cairo_gstate_t *gstate;
|
||||
cairo_point_t current_point;
|
||||
} cpp_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cpp_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cpp_t *cpp = closure;
|
||||
cairo_path_data_t *data = cpp->data;
|
||||
double x, y;
|
||||
|
||||
x = _cairo_fixed_to_double (point->x);
|
||||
y = _cairo_fixed_to_double (point->y);
|
||||
|
||||
_cairo_gstate_backend_to_user (cpp->gstate, &x, &y);
|
||||
|
||||
data->header.type = CAIRO_PATH_MOVE_TO;
|
||||
data->header.length = 2;
|
||||
|
||||
/* We index from 1 to leave room for data->header */
|
||||
data[1].point.x = x;
|
||||
data[1].point.y = y;
|
||||
|
||||
cpp->data += data->header.length;
|
||||
|
||||
cpp->current_point = *point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpp_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cpp_t *cpp = closure;
|
||||
cairo_path_data_t *data = cpp->data;
|
||||
double x, y;
|
||||
|
||||
x = _cairo_fixed_to_double (point->x);
|
||||
y = _cairo_fixed_to_double (point->y);
|
||||
|
||||
_cairo_gstate_backend_to_user (cpp->gstate, &x, &y);
|
||||
|
||||
data->header.type = CAIRO_PATH_LINE_TO;
|
||||
data->header.length = 2;
|
||||
|
||||
/* We index from 1 to leave room for data->header */
|
||||
data[1].point.x = x;
|
||||
data[1].point.y = y;
|
||||
|
||||
cpp->data += data->header.length;
|
||||
|
||||
cpp->current_point = *point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpp_curve_to (void *closure,
|
||||
cairo_point_t *p1,
|
||||
cairo_point_t *p2,
|
||||
cairo_point_t *p3)
|
||||
{
|
||||
cpp_t *cpp = closure;
|
||||
cairo_path_data_t *data = cpp->data;
|
||||
double x1, y1;
|
||||
double x2, y2;
|
||||
double x3, y3;
|
||||
|
||||
x1 = _cairo_fixed_to_double (p1->x);
|
||||
y1 = _cairo_fixed_to_double (p1->y);
|
||||
_cairo_gstate_backend_to_user (cpp->gstate, &x1, &y1);
|
||||
|
||||
x2 = _cairo_fixed_to_double (p2->x);
|
||||
y2 = _cairo_fixed_to_double (p2->y);
|
||||
_cairo_gstate_backend_to_user (cpp->gstate, &x2, &y2);
|
||||
|
||||
x3 = _cairo_fixed_to_double (p3->x);
|
||||
y3 = _cairo_fixed_to_double (p3->y);
|
||||
_cairo_gstate_backend_to_user (cpp->gstate, &x3, &y3);
|
||||
|
||||
data->header.type = CAIRO_PATH_CURVE_TO;
|
||||
data->header.length = 4;
|
||||
|
||||
/* We index from 1 to leave room for data->header */
|
||||
data[1].point.x = x1;
|
||||
data[1].point.y = y1;
|
||||
|
||||
data[2].point.x = x2;
|
||||
data[2].point.y = y2;
|
||||
|
||||
data[3].point.x = x3;
|
||||
data[3].point.y = y3;
|
||||
|
||||
cpp->data += data->header.length;
|
||||
|
||||
cpp->current_point = *p3;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cpp_close_path (void *closure)
|
||||
{
|
||||
cpp_t *cpp = closure;
|
||||
cairo_path_data_t *data = cpp->data;
|
||||
|
||||
data->header.type = CAIRO_PATH_CLOSE_PATH;
|
||||
data->header.length = 1;
|
||||
|
||||
cpp->data += data->header.length;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_populate (cairo_path_t *path,
|
||||
cairo_path_fixed_t *path_fixed,
|
||||
cairo_gstate_t *gstate,
|
||||
cairo_bool_t flatten)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cpp_t cpp;
|
||||
|
||||
cpp.data = path->data;
|
||||
cpp.gstate = gstate;
|
||||
cpp.current_point.x = 0;
|
||||
cpp.current_point.y = 0;
|
||||
|
||||
if (flatten) {
|
||||
double tolerance = _cairo_gstate_get_tolerance (gstate);
|
||||
status = _cairo_path_fixed_interpret_flat (path_fixed,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cpp_move_to,
|
||||
_cpp_line_to,
|
||||
_cpp_close_path,
|
||||
&cpp,
|
||||
tolerance);
|
||||
} else {
|
||||
status = _cairo_path_fixed_interpret (path_fixed,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cpp_move_to,
|
||||
_cpp_line_to,
|
||||
_cpp_curve_to,
|
||||
_cpp_close_path,
|
||||
&cpp);
|
||||
}
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Sanity check the count */
|
||||
assert (cpp.data - path->data == path->num_data);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_path_t *
|
||||
_cairo_path_create_in_error (cairo_status_t status)
|
||||
{
|
||||
cairo_path_t *path;
|
||||
|
||||
/* special case NO_MEMORY so as to avoid allocations */
|
||||
if (status == CAIRO_STATUS_NO_MEMORY)
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
|
||||
path = malloc (sizeof (cairo_path_t));
|
||||
if (path == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->num_data = 0;
|
||||
path->data = NULL;
|
||||
path->status = status;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static cairo_path_t *
|
||||
_cairo_path_create_internal (cairo_path_fixed_t *path_fixed,
|
||||
cairo_gstate_t *gstate,
|
||||
cairo_bool_t flatten)
|
||||
{
|
||||
cairo_path_t *path;
|
||||
|
||||
path = malloc (sizeof (cairo_path_t));
|
||||
if (path == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->num_data = _cairo_path_count (path, path_fixed,
|
||||
_cairo_gstate_get_tolerance (gstate),
|
||||
flatten);
|
||||
if (path->num_data < 0) {
|
||||
free (path);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
if (path->num_data) {
|
||||
path->data = _cairo_malloc_ab (path->num_data,
|
||||
sizeof (cairo_path_data_t));
|
||||
if (path->data == NULL) {
|
||||
free (path);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->status = _cairo_path_populate (path, path_fixed,
|
||||
gstate, flatten);
|
||||
} else {
|
||||
path->data = NULL;
|
||||
path->status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_path_destroy:
|
||||
* @path: a path previously returned by either cairo_copy_path() or
|
||||
* cairo_copy_path_flat().
|
||||
*
|
||||
* Immediately releases all memory associated with @path. After a call
|
||||
* to cairo_path_destroy() the @path pointer is no longer valid and
|
||||
* should not be used further.
|
||||
*
|
||||
* Note: cairo_path_destroy() should only be called with a
|
||||
* pointer to a #cairo_path_t returned by a cairo function. Any path
|
||||
* that is created manually (ie. outside of cairo) should be destroyed
|
||||
* manually as well.
|
||||
**/
|
||||
void
|
||||
cairo_path_destroy (cairo_path_t *path)
|
||||
{
|
||||
if (path == NULL || path == &_cairo_path_nil)
|
||||
return;
|
||||
|
||||
if (path->data)
|
||||
free (path->data);
|
||||
|
||||
free (path);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_path_create:
|
||||
* @path: a fixed-point, device-space path to be converted and copied
|
||||
* @gstate: the current graphics state
|
||||
*
|
||||
* Creates a user-space #cairo_path_t copy of the given device-space
|
||||
* @path. The @gstate parameter provides the inverse CTM for the
|
||||
* conversion.
|
||||
*
|
||||
* Return value: the new copy of the path. If there is insufficient
|
||||
* memory a pointer to a special static nil #cairo_path_t will be
|
||||
* returned instead with status==%CAIRO_STATUS_NO_MEMORY and
|
||||
* data==%NULL.
|
||||
**/
|
||||
cairo_path_t *
|
||||
_cairo_path_create (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate)
|
||||
{
|
||||
return _cairo_path_create_internal (path, gstate, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_path_create_flat:
|
||||
* @path: a fixed-point, device-space path to be flattened, converted and copied
|
||||
* @gstate: the current graphics state
|
||||
*
|
||||
* Creates a flattened, user-space #cairo_path_t copy of the given
|
||||
* device-space @path. The @gstate parameter provide the inverse CTM
|
||||
* for the conversion, as well as the tolerance value to control the
|
||||
* accuracy of the flattening.
|
||||
*
|
||||
* Return value: the flattened copy of the path. If there is insufficient
|
||||
* memory a pointer to a special static nil #cairo_path_t will be
|
||||
* returned instead with status==%CAIRO_STATUS_NO_MEMORY and
|
||||
* data==%NULL.
|
||||
**/
|
||||
cairo_path_t *
|
||||
_cairo_path_create_flat (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate)
|
||||
{
|
||||
return _cairo_path_create_internal (path, gstate, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_path_append_to_context:
|
||||
* @path: the path data to be appended
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Append @path to the current path within @cr.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_INVALID_PATH_DATA if the data in @path
|
||||
* is invalid, and %CAIRO_STATUS_SUCCESS otherwise.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_path_append_to_context (const cairo_path_t *path,
|
||||
cairo_t *cr)
|
||||
{
|
||||
int i;
|
||||
cairo_path_data_t *p;
|
||||
cairo_status_t status;
|
||||
|
||||
for (i=0; i < path->num_data; i += path->data[i].header.length) {
|
||||
p = &path->data[i];
|
||||
switch (p->header.type) {
|
||||
case CAIRO_PATH_MOVE_TO:
|
||||
if (p->header.length < 2)
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_move_to (cr,
|
||||
p[1].point.x, p[1].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_LINE_TO:
|
||||
if (p->header.length < 2)
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_line_to (cr,
|
||||
p[1].point.x, p[1].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_CURVE_TO:
|
||||
if (p->header.length < 4)
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_curve_to (cr,
|
||||
p[1].point.x, p[1].point.y,
|
||||
p[2].point.x, p[2].point.y,
|
||||
p[3].point.x, p[3].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_CLOSE_PATH:
|
||||
if (p->header.length < 1)
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_close_path (cr);
|
||||
break;
|
||||
default:
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
}
|
||||
|
||||
status = cairo_status (cr);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
2528
uppdev/plugin/cairo/lib/cairo-pattern.c
Normal file
2528
uppdev/plugin/cairo/lib/cairo-pattern.c
Normal file
File diff suppressed because it is too large
Load diff
165
uppdev/plugin/cairo/lib/cairo-pdf-operators-private.h
Normal file
165
uppdev/plugin/cairo/lib/cairo-pdf-operators-private.h
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
* Copyright © 2007 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PDF_OPERATORS_H
|
||||
#define CAIRO_PDF_OPERATORS_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
/* The glyph buffer size is based on the expected maximum glyphs in a
|
||||
* line so that an entire line can be emitted in as one string. If the
|
||||
* glyphs in a line exceeds this size the only downside is the slight
|
||||
* overhead of emitting two strings.
|
||||
*/
|
||||
#define PDF_GLYPH_BUFFER_SIZE 200
|
||||
|
||||
typedef cairo_status_t (*cairo_pdf_operators_use_font_subset_t) (unsigned int font_id,
|
||||
unsigned int subset_id,
|
||||
void *closure);
|
||||
|
||||
typedef struct _cairo_pdf_glyph {
|
||||
unsigned int glyph_index;
|
||||
double x_position;
|
||||
double x_advance;
|
||||
} cairo_pdf_glyph_t;
|
||||
|
||||
typedef struct _cairo_pdf_operators {
|
||||
cairo_output_stream_t *stream;
|
||||
cairo_matrix_t cairo_to_pdf;
|
||||
cairo_scaled_font_subsets_t *font_subsets;
|
||||
cairo_pdf_operators_use_font_subset_t use_font_subset;
|
||||
void *use_font_subset_closure;
|
||||
cairo_bool_t in_text_object; /* inside BT/ET pair */
|
||||
|
||||
/* PDF text state */
|
||||
cairo_bool_t is_new_text_object; /* text object started but matrix and font not yet selected */
|
||||
unsigned int font_id;
|
||||
unsigned int subset_id;
|
||||
cairo_matrix_t text_matrix; /* PDF text matrix (Tlm in the PDF reference) */
|
||||
cairo_matrix_t cairo_to_pdftext; /* translate cairo coords to PDF text space */
|
||||
cairo_matrix_t font_matrix_inverse;
|
||||
double cur_x; /* Current position in PDF text space (Tm in the PDF reference) */
|
||||
double cur_y;
|
||||
int hex_width;
|
||||
int num_glyphs;
|
||||
cairo_pdf_glyph_t glyphs[PDF_GLYPH_BUFFER_SIZE];
|
||||
|
||||
/* PDF line style */
|
||||
cairo_bool_t has_line_style;
|
||||
double line_width;
|
||||
cairo_line_cap_t line_cap;
|
||||
cairo_line_join_t line_join;
|
||||
double miter_limit;
|
||||
cairo_bool_t has_dashes;
|
||||
} cairo_pdf_operators_t;
|
||||
|
||||
cairo_private void
|
||||
_cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_output_stream_t *stream,
|
||||
cairo_matrix_t *cairo_to_pdf,
|
||||
cairo_scaled_font_subsets_t *font_subsets);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pdf_operators_fini (cairo_pdf_operators_t *pdf_operators);
|
||||
|
||||
cairo_private void
|
||||
_cairo_pdf_operators_set_font_subsets_callback (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_pdf_operators_use_font_subset_t use_font_subset,
|
||||
void *closure);
|
||||
|
||||
cairo_private void
|
||||
_cairo_pdf_operators_set_stream (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_output_stream_t *stream);
|
||||
|
||||
|
||||
cairo_private void
|
||||
_cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_matrix_t *cairo_to_pdf);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators);
|
||||
|
||||
cairo_private void
|
||||
_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_stroke_style_t *style,
|
||||
double scale);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
const cairo_text_cluster_t *clusters,
|
||||
int num_clusters,
|
||||
cairo_text_cluster_flags_t cluster_flags,
|
||||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
#endif /* CAIRO_PDF_OPERATORS_H */
|
||||
1450
uppdev/plugin/cairo/lib/cairo-pdf-operators.c
Normal file
1450
uppdev/plugin/cairo/lib/cairo-pdf-operators.c
Normal file
File diff suppressed because it is too large
Load diff
171
uppdev/plugin/cairo/lib/cairo-pdf-surface-private.h
Normal file
171
uppdev/plugin/cairo/lib/cairo-pdf-surface-private.h
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
* Copyright © 2007, 2008 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PDF_SURFACE_PRIVATE_H
|
||||
#define CAIRO_PDF_SURFACE_PRIVATE_H
|
||||
|
||||
#include "cairo-pdf.h"
|
||||
|
||||
#include "cairo-surface-private.h"
|
||||
#include "cairo-pdf-operators-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
typedef struct _cairo_pdf_resource {
|
||||
unsigned int id;
|
||||
} cairo_pdf_resource_t;
|
||||
|
||||
typedef struct _cairo_pdf_group_resources {
|
||||
cairo_array_t alphas;
|
||||
cairo_array_t smasks;
|
||||
cairo_array_t patterns;
|
||||
cairo_array_t xobjects;
|
||||
cairo_array_t fonts;
|
||||
} cairo_pdf_group_resources_t;
|
||||
|
||||
typedef struct _cairo_pdf_pattern {
|
||||
double width;
|
||||
double height;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_pdf_resource_t pattern_res;
|
||||
cairo_pdf_resource_t gstate_res;
|
||||
} cairo_pdf_pattern_t;
|
||||
|
||||
typedef enum _cairo_pdf_operation {
|
||||
PDF_PAINT,
|
||||
PDF_MASK,
|
||||
PDF_FILL,
|
||||
PDF_STROKE,
|
||||
PDF_SHOW_GLYPHS
|
||||
} cairo_pdf_operation_t;
|
||||
|
||||
typedef struct _cairo_pdf_smask_group
|
||||
{
|
||||
double width;
|
||||
double height;
|
||||
cairo_pdf_resource_t group_res;
|
||||
cairo_pdf_operation_t operation;
|
||||
cairo_pattern_t *source;
|
||||
cairo_pdf_resource_t source_res;
|
||||
cairo_pattern_t *mask;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
cairo_stroke_style_t *style;
|
||||
cairo_matrix_t ctm;
|
||||
cairo_matrix_t ctm_inverse;
|
||||
char *utf8;
|
||||
int utf8_len;
|
||||
cairo_glyph_t *glyphs;
|
||||
int num_glyphs;
|
||||
cairo_text_cluster_t *clusters;
|
||||
int num_clusters;
|
||||
cairo_bool_t cluster_flags;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
} cairo_pdf_smask_group_t;
|
||||
|
||||
typedef struct _cairo_pdf_surface cairo_pdf_surface_t;
|
||||
|
||||
struct _cairo_pdf_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* Prefer the name "output" here to avoid confusion over the
|
||||
* structure within a PDF document known as a "stream". */
|
||||
cairo_output_stream_t *output;
|
||||
|
||||
double width;
|
||||
double height;
|
||||
cairo_matrix_t cairo_to_pdf;
|
||||
|
||||
cairo_array_t objects;
|
||||
cairo_array_t pages;
|
||||
cairo_array_t rgb_linear_functions;
|
||||
cairo_array_t alpha_linear_functions;
|
||||
cairo_array_t patterns;
|
||||
cairo_array_t smask_groups;
|
||||
cairo_array_t knockout_group;
|
||||
|
||||
cairo_scaled_font_subsets_t *font_subsets;
|
||||
cairo_array_t fonts;
|
||||
|
||||
cairo_pdf_resource_t next_available_resource;
|
||||
cairo_pdf_resource_t pages_resource;
|
||||
|
||||
cairo_bool_t compress_content;
|
||||
|
||||
cairo_pdf_resource_t content;
|
||||
cairo_pdf_resource_t content_resources;
|
||||
cairo_pdf_group_resources_t resources;
|
||||
cairo_bool_t has_fallback_images;
|
||||
|
||||
struct {
|
||||
cairo_bool_t active;
|
||||
cairo_pdf_resource_t self;
|
||||
cairo_pdf_resource_t length;
|
||||
long start_offset;
|
||||
cairo_bool_t compressed;
|
||||
cairo_output_stream_t *old_output;
|
||||
} pdf_stream;
|
||||
|
||||
struct {
|
||||
cairo_bool_t active;
|
||||
cairo_output_stream_t *stream;
|
||||
cairo_output_stream_t *mem_stream;
|
||||
cairo_output_stream_t *old_output;
|
||||
cairo_pdf_resource_t resource;
|
||||
cairo_bool_t is_knockout;
|
||||
} group_stream;
|
||||
|
||||
cairo_pdf_operators_t pdf_operators;
|
||||
cairo_paginated_mode_t paginated_mode;
|
||||
cairo_bool_t select_pattern_gstate_saved;
|
||||
|
||||
cairo_bool_t force_fallbacks;
|
||||
|
||||
cairo_bool_t current_pattern_is_solid_color;
|
||||
cairo_bool_t current_color_is_stroke;
|
||||
double current_color_red;
|
||||
double current_color_green;
|
||||
double current_color_blue;
|
||||
double current_color_alpha;
|
||||
|
||||
cairo_surface_t *paginated_surface;
|
||||
};
|
||||
|
||||
#endif /* CAIRO_PDF_SURFACE_PRIVATE_H */
|
||||
4996
uppdev/plugin/cairo/lib/cairo-pdf-surface.c
Normal file
4996
uppdev/plugin/cairo/lib/cairo-pdf-surface.c
Normal file
File diff suppressed because it is too large
Load diff
68
uppdev/plugin/cairo/lib/cairo-pdf.h
Normal file
68
uppdev/plugin/cairo/lib/cairo-pdf.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PDF_H
|
||||
#define CAIRO_PDF_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_PDF_SURFACE
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_pdf_surface_create (const char *filename,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
void *closure,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public void
|
||||
cairo_pdf_surface_set_size (cairo_surface_t *surface,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_PDF_SURFACE */
|
||||
# error Cairo was not compiled with support for the pdf backend
|
||||
#endif /* CAIRO_HAS_PDF_SURFACE */
|
||||
|
||||
#endif /* CAIRO_PDF_H */
|
||||
491
uppdev/plugin/cairo/lib/cairo-pen.c
Normal file
491
uppdev/plugin/cairo/lib/cairo-pen.c
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static int
|
||||
_cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *matrix);
|
||||
|
||||
static void
|
||||
_cairo_pen_compute_slopes (cairo_pen_t *pen);
|
||||
|
||||
static void
|
||||
_cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_direction_t dir, cairo_polygon_t *polygon);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen,
|
||||
double radius,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm)
|
||||
{
|
||||
int i;
|
||||
int reflect;
|
||||
|
||||
pen->radius = radius;
|
||||
pen->tolerance = tolerance;
|
||||
|
||||
reflect = _cairo_matrix_compute_determinant (ctm) < 0.;
|
||||
|
||||
pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
|
||||
radius,
|
||||
ctm);
|
||||
|
||||
if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices,
|
||||
sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
pen->vertices = pen->vertices_embedded;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute pen coordinates. To generate the right ellipse, compute points around
|
||||
* a circle in user space and transform them to device space. To get a consistent
|
||||
* orientation in device space, flip the pen if the transformation matrix
|
||||
* is reflecting
|
||||
*/
|
||||
for (i=0; i < pen->num_vertices; i++) {
|
||||
double theta = 2 * M_PI * i / (double) pen->num_vertices;
|
||||
double dx = radius * cos (reflect ? -theta : theta);
|
||||
double dy = radius * sin (reflect ? -theta : theta);
|
||||
cairo_pen_vertex_t *v = &pen->vertices[i];
|
||||
cairo_matrix_transform_distance (ctm, &dx, &dy);
|
||||
v->point.x = _cairo_fixed_from_double (dx);
|
||||
v->point.y = _cairo_fixed_from_double (dy);
|
||||
}
|
||||
|
||||
_cairo_pen_compute_slopes (pen);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_pen_fini (cairo_pen_t *pen)
|
||||
{
|
||||
if (pen->vertices != pen->vertices_embedded)
|
||||
free (pen->vertices);
|
||||
|
||||
pen->vertices = pen->vertices_embedded;
|
||||
pen->num_vertices = 0;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other)
|
||||
{
|
||||
*pen = *other;
|
||||
|
||||
pen->vertices = pen->vertices_embedded;
|
||||
if (pen->num_vertices) {
|
||||
if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices,
|
||||
sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
memcpy (pen->vertices, other->vertices,
|
||||
pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int num_vertices;
|
||||
int i;
|
||||
|
||||
num_vertices = pen->num_vertices + num_points;
|
||||
if (num_vertices > ARRAY_LENGTH (pen->vertices_embedded) ||
|
||||
pen->vertices != pen->vertices_embedded)
|
||||
{
|
||||
cairo_pen_vertex_t *vertices;
|
||||
|
||||
if (pen->vertices == pen->vertices_embedded) {
|
||||
vertices = _cairo_malloc_ab (num_vertices,
|
||||
sizeof (cairo_pen_vertex_t));
|
||||
if (vertices == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (vertices, pen->vertices,
|
||||
pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
} else {
|
||||
vertices = _cairo_realloc_ab (pen->vertices,
|
||||
num_vertices,
|
||||
sizeof (cairo_pen_vertex_t));
|
||||
if (vertices == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
pen->vertices = vertices;
|
||||
}
|
||||
|
||||
pen->num_vertices = num_vertices;
|
||||
|
||||
/* initialize new vertices */
|
||||
for (i=0; i < num_points; i++)
|
||||
pen->vertices[pen->num_vertices-num_points+i].point = point[i];
|
||||
|
||||
status = _cairo_hull_compute (pen->vertices, &pen->num_vertices);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_pen_compute_slopes (pen);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
The circular pen in user space is transformed into an ellipse in
|
||||
device space.
|
||||
|
||||
We construct the pen by computing points along the circumference
|
||||
using equally spaced angles.
|
||||
|
||||
We show that this approximation to the ellipse has maximum error at the
|
||||
major axis of the ellipse.
|
||||
|
||||
Set
|
||||
|
||||
M = major axis length
|
||||
m = minor axis length
|
||||
|
||||
Align 'M' along the X axis and 'm' along the Y axis and draw
|
||||
an ellipse parameterized by angle 't':
|
||||
|
||||
x = M cos t y = m sin t
|
||||
|
||||
Perturb t by ± d and compute two new points (x+,y+), (x-,y-).
|
||||
The distance from the average of these two points to (x,y) represents
|
||||
the maximum error in approximating the ellipse with a polygon formed
|
||||
from vertices 2∆ radians apart.
|
||||
|
||||
x+ = M cos (t+∆) y+ = m sin (t+∆)
|
||||
x- = M cos (t-∆) y- = m sin (t-∆)
|
||||
|
||||
Now compute the approximation error, E:
|
||||
|
||||
Ex = (x - (x+ + x-) / 2)
|
||||
Ex = (M cos(t) - (Mcos(t+∆) + Mcos(t-∆))/2)
|
||||
= M (cos(t) - (cos(t)cos(∆) + sin(t)sin(∆) +
|
||||
cos(t)cos(∆) - sin(t)sin(∆))/2)
|
||||
= M(cos(t) - cos(t)cos(∆))
|
||||
= M cos(t) (1 - cos(∆))
|
||||
|
||||
Ey = y - (y+ - y-) / 2
|
||||
= m sin (t) - (m sin(t+∆) + m sin(t-∆)) / 2
|
||||
= m (sin(t) - (sin(t)cos(∆) + cos(t)sin(∆) +
|
||||
sin(t)cos(∆) - cos(t)sin(∆))/2)
|
||||
= m (sin(t) - sin(t)cos(∆))
|
||||
= m sin(t) (1 - cos(∆))
|
||||
|
||||
E² = Ex² + Ey²
|
||||
= (M cos(t) (1 - cos (∆)))² + (m sin(t) (1-cos(∆)))²
|
||||
= (1 - cos(∆))² (M² cos²(t) + m² sin²(t))
|
||||
= (1 - cos(∆))² ((m² + M² - m²) cos² (t) + m² sin²(t))
|
||||
= (1 - cos(∆))² (M² - m²) cos² (t) + (1 - cos(∆))² m²
|
||||
|
||||
Find the extremum by differentiation wrt t and setting that to zero
|
||||
|
||||
∂(E²)/∂(t) = (1-cos(∆))² (M² - m²) (-2 cos(t) sin(t))
|
||||
|
||||
0 = 2 cos (t) sin (t)
|
||||
0 = sin (2t)
|
||||
t = nπ
|
||||
|
||||
Which is to say that the maximum and minimum errors occur on the
|
||||
axes of the ellipse at 0 and π radians:
|
||||
|
||||
E²(0) = (1-cos(∆))² (M² - m²) + (1-cos(∆))² m²
|
||||
= (1-cos(∆))² M²
|
||||
E²(π) = (1-cos(∆))² m²
|
||||
|
||||
maximum error = M (1-cos(∆))
|
||||
minimum error = m (1-cos(∆))
|
||||
|
||||
We must make maximum error ≤ tolerance, so compute the ∆ needed:
|
||||
|
||||
tolerance = M (1-cos(∆))
|
||||
tolerance / M = 1 - cos (∆)
|
||||
cos(∆) = 1 - tolerance/M
|
||||
∆ = acos (1 - tolerance / M);
|
||||
|
||||
Remembering that ∆ is half of our angle between vertices,
|
||||
the number of vertices is then
|
||||
|
||||
vertices = ceil(2π/2∆).
|
||||
= ceil(π/∆).
|
||||
|
||||
Note that this also equation works for M == m (a circle) as it
|
||||
doesn't matter where on the circle the error is computed.
|
||||
*/
|
||||
|
||||
static int
|
||||
_cairo_pen_vertices_needed (double tolerance,
|
||||
double radius,
|
||||
cairo_matrix_t *matrix)
|
||||
{
|
||||
/*
|
||||
* the pen is a circle that gets transformed to an ellipse by matrix.
|
||||
* compute major axis length for a pen with the specified radius.
|
||||
* we don't need the minor axis length.
|
||||
*/
|
||||
|
||||
double major_axis = _cairo_matrix_transformed_circle_major_axis(matrix, radius);
|
||||
|
||||
/*
|
||||
* compute number of vertices needed
|
||||
*/
|
||||
int num_vertices;
|
||||
|
||||
/* Where tolerance / M is > 1, we use 4 points */
|
||||
if (tolerance >= major_axis) {
|
||||
num_vertices = 4;
|
||||
} else {
|
||||
double delta = acos (1 - tolerance / major_axis);
|
||||
num_vertices = ceil (M_PI / delta);
|
||||
|
||||
/* number of vertices must be even */
|
||||
if (num_vertices % 2)
|
||||
num_vertices++;
|
||||
|
||||
/* And we must always have at least 4 vertices. */
|
||||
if (num_vertices < 4)
|
||||
num_vertices = 4;
|
||||
}
|
||||
|
||||
return num_vertices;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pen_compute_slopes (cairo_pen_t *pen)
|
||||
{
|
||||
int i, i_prev;
|
||||
cairo_pen_vertex_t *prev, *v, *next;
|
||||
|
||||
for (i=0, i_prev = pen->num_vertices - 1;
|
||||
i < pen->num_vertices;
|
||||
i_prev = i++) {
|
||||
prev = &pen->vertices[i_prev];
|
||||
v = &pen->vertices[i];
|
||||
next = &pen->vertices[(i + 1) % pen->num_vertices];
|
||||
|
||||
_cairo_slope_init (&v->slope_cw, &prev->point, &v->point);
|
||||
_cairo_slope_init (&v->slope_ccw, &v->point, &next->point);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Find active pen vertex for clockwise edge of stroke at the given slope.
|
||||
*
|
||||
* The strictness of the inequalities here is delicate. The issue is
|
||||
* that the slope_ccw member of one pen vertex will be equivalent to
|
||||
* the slope_cw member of the next pen vertex in a counterclockwise
|
||||
* order. However, for this function, we care strongly about which
|
||||
* vertex is returned.
|
||||
*
|
||||
* [I think the "care strongly" above has to do with ensuring that the
|
||||
* pen's "extra points" from the spline's initial and final slopes are
|
||||
* properly found when beginning the spline stroking.]
|
||||
*/
|
||||
void
|
||||
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_t *slope,
|
||||
int *active)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < pen->num_vertices; i++) {
|
||||
if ((_cairo_slope_compare (slope, &pen->vertices[i].slope_ccw) < 0) &&
|
||||
(_cairo_slope_compare (slope, &pen->vertices[i].slope_cw) >= 0))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the desired slope cannot be found between any of the pen
|
||||
* vertices, then we must have a degenerate pen, (such as a pen
|
||||
* that's been transformed to a line). In that case, we consider
|
||||
* the first pen vertex as the appropriate clockwise vertex.
|
||||
*/
|
||||
if (i == pen->num_vertices)
|
||||
i = 0;
|
||||
|
||||
*active = i;
|
||||
}
|
||||
|
||||
/* Find active pen vertex for counterclockwise edge of stroke at the given slope.
|
||||
*
|
||||
* Note: See the comments for _cairo_pen_find_active_cw_vertex_index
|
||||
* for some details about the strictness of the inequalities here.
|
||||
*/
|
||||
void
|
||||
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_t *slope,
|
||||
int *active)
|
||||
{
|
||||
int i;
|
||||
cairo_slope_t slope_reverse;
|
||||
|
||||
slope_reverse = *slope;
|
||||
slope_reverse.dx = -slope_reverse.dx;
|
||||
slope_reverse.dy = -slope_reverse.dy;
|
||||
|
||||
for (i=pen->num_vertices-1; i >= 0; i--) {
|
||||
if ((_cairo_slope_compare (&pen->vertices[i].slope_ccw, &slope_reverse) >= 0) &&
|
||||
(_cairo_slope_compare (&pen->vertices[i].slope_cw, &slope_reverse) < 0))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the desired slope cannot be found between any of the pen
|
||||
* vertices, then we must have a degenerate pen, (such as a pen
|
||||
* that's been transformed to a line). In that case, we consider
|
||||
* the last pen vertex as the appropriate counterclockwise vertex.
|
||||
*/
|
||||
if (i < 0)
|
||||
i = pen->num_vertices - 1;
|
||||
|
||||
*active = i;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pen_stroke_spline_half (cairo_pen_t *pen,
|
||||
cairo_spline_t *spline,
|
||||
cairo_direction_t dir,
|
||||
cairo_polygon_t *polygon)
|
||||
{
|
||||
int i;
|
||||
int start, stop, step;
|
||||
int active = 0;
|
||||
cairo_point_t hull_point;
|
||||
cairo_slope_t slope, initial_slope, final_slope;
|
||||
cairo_point_t *point = spline->points;
|
||||
int num_points = spline->num_points;
|
||||
|
||||
if (dir == CAIRO_DIRECTION_FORWARD) {
|
||||
start = 0;
|
||||
stop = num_points;
|
||||
step = 1;
|
||||
initial_slope = spline->initial_slope;
|
||||
final_slope = spline->final_slope;
|
||||
} else {
|
||||
start = num_points - 1;
|
||||
stop = -1;
|
||||
step = -1;
|
||||
initial_slope = spline->final_slope;
|
||||
initial_slope.dx = -initial_slope.dx;
|
||||
initial_slope.dy = -initial_slope.dy;
|
||||
final_slope = spline->initial_slope;
|
||||
final_slope.dx = -final_slope.dx;
|
||||
final_slope.dy = -final_slope.dy;
|
||||
}
|
||||
|
||||
_cairo_pen_find_active_cw_vertex_index (pen,
|
||||
&initial_slope,
|
||||
&active);
|
||||
|
||||
i = start;
|
||||
while (i != stop) {
|
||||
hull_point.x = point[i].x + pen->vertices[active].point.x;
|
||||
hull_point.y = point[i].y + pen->vertices[active].point.y;
|
||||
|
||||
_cairo_polygon_line_to (polygon, &hull_point);
|
||||
|
||||
if (i + step == stop)
|
||||
slope = final_slope;
|
||||
else
|
||||
_cairo_slope_init (&slope, &point[i], &point[i+step]);
|
||||
|
||||
/* The strict inequalities here ensure that if a spline slope
|
||||
* compares identically with either of the slopes of the
|
||||
* active vertex, then it remains the active vertex. This is
|
||||
* very important since otherwise we can trigger an infinite
|
||||
* loop in the case of a degenerate pen, (a line), where
|
||||
* neither vertex considers itself active for the slope---one
|
||||
* will consider it as equal and reject, and the other will
|
||||
* consider it unequal and reject. This is due to the inherent
|
||||
* ambiguity when comparing slopes that differ by exactly
|
||||
* pi. */
|
||||
if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_ccw) > 0) {
|
||||
if (++active == pen->num_vertices)
|
||||
active = 0;
|
||||
} else if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_cw) < 0) {
|
||||
if (--active == -1)
|
||||
active = pen->num_vertices - 1;
|
||||
} else {
|
||||
i += step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute outline of a given spline using the pen.
|
||||
The trapezoids needed to fill that outline will be added to traps
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_pen_stroke_spline (cairo_pen_t *pen,
|
||||
cairo_spline_t *spline,
|
||||
double tolerance,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_polygon_t polygon;
|
||||
|
||||
/* If the line width is so small that the pen is reduced to a
|
||||
single point, then we have nothing to do. */
|
||||
if (pen->num_vertices <= 1)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_polygon_init (&polygon);
|
||||
|
||||
status = _cairo_spline_decompose (spline, tolerance);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
_cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon);
|
||||
|
||||
_cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon);
|
||||
|
||||
_cairo_polygon_close (&polygon);
|
||||
status = _cairo_polygon_status (&polygon);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
|
||||
BAIL:
|
||||
_cairo_polygon_fini (&polygon);
|
||||
|
||||
return status;
|
||||
}
|
||||
708
uppdev/plugin/cairo/lib/cairo-png.c
Normal file
708
uppdev/plugin/cairo/lib/cairo-png.c
Normal file
|
|
@ -0,0 +1,708 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <png.h>
|
||||
|
||||
/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
|
||||
static void
|
||||
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *b = &data[i];
|
||||
uint32_t pixel;
|
||||
uint8_t alpha;
|
||||
|
||||
memcpy (&pixel, b, sizeof (uint32_t));
|
||||
alpha = (pixel & 0xff000000) >> 24;
|
||||
if (alpha == 0) {
|
||||
b[0] = b[1] = b[2] = b[3] = 0;
|
||||
} else {
|
||||
b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
|
||||
b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
|
||||
b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
|
||||
b[3] = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Converts native endian xRGB => RGBx bytes */
|
||||
static void
|
||||
convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *b = &data[i];
|
||||
uint32_t pixel;
|
||||
|
||||
memcpy (&pixel, b, sizeof (uint32_t));
|
||||
|
||||
b[0] = (pixel & 0xff0000) >> 16;
|
||||
b[1] = (pixel & 0x00ff00) >> 8;
|
||||
b[2] = (pixel & 0x0000ff) >> 0;
|
||||
b[3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use a couple of simple error callbacks that do not print anything to
|
||||
* stderr and rely on the user to check for errors via the #cairo_status_t
|
||||
* return.
|
||||
*/
|
||||
static void
|
||||
png_simple_error_callback (png_structp png,
|
||||
png_const_charp error_msg)
|
||||
{
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
|
||||
/* default to the most likely error */
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
longjmp (png_jmpbuf (png), 1);
|
||||
#endif
|
||||
|
||||
/* if we get here, then we have to choice but to abort ... */
|
||||
}
|
||||
|
||||
static void
|
||||
png_simple_warning_callback (png_structp png,
|
||||
png_const_charp error_msg)
|
||||
{
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
|
||||
/* default to the most likely error */
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/* png does not expect to abort and will try to tidy up after a warning */
|
||||
}
|
||||
|
||||
|
||||
/* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
|
||||
* Otherwise, we will segfault if we are writing to a stream. */
|
||||
static void
|
||||
png_simple_output_flush_fn (png_structp png_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
write_png (cairo_surface_t *surface,
|
||||
png_rw_ptr write_func,
|
||||
void *closure)
|
||||
{
|
||||
int i;
|
||||
cairo_status_t status;
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
png_struct *png;
|
||||
png_info *info;
|
||||
png_byte **volatile rows = NULL;
|
||||
png_color_16 white;
|
||||
int png_color_type;
|
||||
int depth;
|
||||
|
||||
status = _cairo_surface_acquire_source_image (surface,
|
||||
&image,
|
||||
&image_extra);
|
||||
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
else if (status)
|
||||
return status;
|
||||
|
||||
/* PNG complains about "Image width or height is zero in IHDR" */
|
||||
if (image->width == 0 || image->height == 0) {
|
||||
status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
goto BAIL1;
|
||||
}
|
||||
|
||||
rows = _cairo_malloc_ab (image->height, sizeof (png_byte*));
|
||||
if (rows == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL1;
|
||||
}
|
||||
|
||||
for (i = 0; i < image->height; i++)
|
||||
rows[i] = (png_byte *) image->data + i * image->stride;
|
||||
|
||||
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
|
||||
png_simple_error_callback,
|
||||
png_simple_warning_callback);
|
||||
if (png == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL2;
|
||||
}
|
||||
|
||||
info = png_create_info_struct (png);
|
||||
if (info == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL3;
|
||||
}
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
if (setjmp (png_jmpbuf (png)))
|
||||
goto BAIL3;
|
||||
#endif
|
||||
|
||||
png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
|
||||
|
||||
switch (image->format) {
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
depth = 8;
|
||||
png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
depth = 8;
|
||||
png_color_type = PNG_COLOR_TYPE_RGB;
|
||||
break;
|
||||
case CAIRO_FORMAT_A8:
|
||||
depth = 8;
|
||||
png_color_type = PNG_COLOR_TYPE_GRAY;
|
||||
break;
|
||||
case CAIRO_FORMAT_A1:
|
||||
depth = 1;
|
||||
png_color_type = PNG_COLOR_TYPE_GRAY;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
png_set_packswap (png);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
goto BAIL3;
|
||||
}
|
||||
|
||||
png_set_IHDR (png, info,
|
||||
image->width,
|
||||
image->height, depth,
|
||||
png_color_type,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
white.gray = (1 << depth) - 1;
|
||||
white.red = white.blue = white.green = white.gray;
|
||||
png_set_bKGD (png, info, &white);
|
||||
|
||||
if (0) { /* XXX extract meta-data from surface (i.e. creation date) */
|
||||
png_time pt;
|
||||
|
||||
png_convert_from_time_t (&pt, time (NULL));
|
||||
png_set_tIME (png, info, &pt);
|
||||
}
|
||||
|
||||
/* We have to call png_write_info() before setting up the write
|
||||
* transformation, since it stores data internally in 'png'
|
||||
* that is needed for the write transformation functions to work.
|
||||
*/
|
||||
png_write_info (png, info);
|
||||
|
||||
if (image->format == CAIRO_FORMAT_ARGB32)
|
||||
png_set_write_user_transform_fn (png, unpremultiply_data);
|
||||
else if (image->format == CAIRO_FORMAT_RGB24)
|
||||
png_set_write_user_transform_fn (png, convert_data_to_bytes);
|
||||
if (image->format == CAIRO_FORMAT_RGB24)
|
||||
png_set_filler (png, 0, PNG_FILLER_AFTER);
|
||||
|
||||
png_write_image (png, rows);
|
||||
png_write_end (png, info);
|
||||
|
||||
BAIL3:
|
||||
png_destroy_write_struct (&png, &info);
|
||||
BAIL2:
|
||||
free (rows);
|
||||
BAIL1:
|
||||
_cairo_surface_release_source_image (surface, image, image_extra);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_write_func (png_structp png, png_bytep data, png_size_t size)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = png_get_io_ptr (png);
|
||||
while (size) {
|
||||
size_t ret = fwrite (data, 1, size, fp);
|
||||
size -= ret;
|
||||
data += ret;
|
||||
if (size && ferror (fp)) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_write_to_png:
|
||||
* @surface: a #cairo_surface_t with pixel contents
|
||||
* @filename: the name of a file to write to
|
||||
*
|
||||
* Writes the contents of @surface to a new file @filename as a PNG
|
||||
* image.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
|
||||
* successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
|
||||
* be allocated for the operation or
|
||||
* %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
|
||||
* pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
|
||||
* while attempting to write the file.
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_surface_write_to_png (cairo_surface_t *surface,
|
||||
const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
fp = fopen (filename, "wb");
|
||||
if (fp == NULL) {
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
default:
|
||||
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
status = write_png (surface, stdio_write_func, fp);
|
||||
|
||||
if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
struct png_write_closure_t {
|
||||
cairo_write_func_t write_func;
|
||||
void *closure;
|
||||
};
|
||||
|
||||
static void
|
||||
stream_write_func (png_structp png, png_bytep data, png_size_t size)
|
||||
{
|
||||
cairo_status_t status;
|
||||
struct png_write_closure_t *png_closure;
|
||||
|
||||
png_closure = png_get_io_ptr (png);
|
||||
status = png_closure->write_func (png_closure->closure, data, size);
|
||||
if (status) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = status;
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_write_to_png_stream:
|
||||
* @surface: a #cairo_surface_t with pixel contents
|
||||
* @write_func: a #cairo_write_func_t
|
||||
* @closure: closure data for the write function
|
||||
*
|
||||
* Writes the image surface to the write function.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
|
||||
* successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
|
||||
* memory could not be allocated for the operation,
|
||||
* %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
|
||||
* pixel contents.
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_surface_write_to_png_stream (cairo_surface_t *surface,
|
||||
cairo_write_func_t write_func,
|
||||
void *closure)
|
||||
{
|
||||
struct png_write_closure_t png_closure;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
png_closure.write_func = write_func;
|
||||
png_closure.closure = closure;
|
||||
|
||||
return write_png (surface, stream_write_func, &png_closure);
|
||||
}
|
||||
slim_hidden_def (cairo_surface_write_to_png_stream);
|
||||
|
||||
static inline int
|
||||
multiply_alpha (int alpha, int color)
|
||||
{
|
||||
int temp = (alpha * color) + 0x80;
|
||||
return ((temp + (temp >> 8)) >> 8);
|
||||
}
|
||||
|
||||
/* Premultiplies data and converts RGBA bytes => native endian */
|
||||
static void
|
||||
premultiply_data (png_structp png,
|
||||
png_row_infop row_info,
|
||||
png_bytep data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *base = &data[i];
|
||||
uint8_t alpha = base[3];
|
||||
uint32_t p;
|
||||
|
||||
if (alpha == 0) {
|
||||
p = 0;
|
||||
} else {
|
||||
uint8_t red = base[0];
|
||||
uint8_t green = base[1];
|
||||
uint8_t blue = base[2];
|
||||
|
||||
if (alpha != 0xff) {
|
||||
red = multiply_alpha (alpha, red);
|
||||
green = multiply_alpha (alpha, green);
|
||||
blue = multiply_alpha (alpha, blue);
|
||||
}
|
||||
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
|
||||
}
|
||||
memcpy (base, &p, sizeof (uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
/* Converts RGBx bytes to native endian xRGB */
|
||||
static void
|
||||
convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *base = &data[i];
|
||||
uint8_t red = base[0];
|
||||
uint8_t green = base[1];
|
||||
uint8_t blue = base[2];
|
||||
uint32_t pixel;
|
||||
|
||||
pixel = (0xff << 24) | (red << 16) | (green << 8) | (blue << 0);
|
||||
memcpy (base, &pixel, sizeof (uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
read_png (png_rw_ptr read_func,
|
||||
void *closure)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
png_struct *png = NULL;
|
||||
png_info *info;
|
||||
png_byte *data = NULL;
|
||||
png_byte **row_pointers = NULL;
|
||||
png_uint_32 png_width, png_height;
|
||||
int depth, color_type, interlace, stride;
|
||||
unsigned int i;
|
||||
cairo_format_t format;
|
||||
cairo_status_t status;
|
||||
|
||||
/* XXX: Perhaps we'll want some other error handlers? */
|
||||
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
|
||||
&status,
|
||||
png_simple_error_callback,
|
||||
png_simple_warning_callback);
|
||||
if (png == NULL) {
|
||||
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
info = png_create_info_struct (png);
|
||||
if (info == NULL) {
|
||||
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
png_set_read_fn (png, closure, read_func);
|
||||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
if (setjmp (png_jmpbuf (png))) {
|
||||
surface = _cairo_surface_create_in_error (status);
|
||||
goto BAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
png_read_info (png, info);
|
||||
|
||||
png_get_IHDR (png, info,
|
||||
&png_width, &png_height, &depth,
|
||||
&color_type, &interlace, NULL, NULL);
|
||||
if (status) { /* catch any early warnings */
|
||||
surface = _cairo_surface_create_in_error (status);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
/* convert palette/gray image to rgb */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_palette_to_rgb (png);
|
||||
|
||||
/* expand gray bit depth if needed */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
#if PNG_LIBPNG_VER >= 10209
|
||||
png_set_expand_gray_1_2_4_to_8 (png);
|
||||
#else
|
||||
png_set_gray_1_2_4_to_8 (png);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* transform transparency to alpha */
|
||||
if (png_get_valid (png, info, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha (png);
|
||||
|
||||
if (depth == 16)
|
||||
png_set_strip_16 (png);
|
||||
|
||||
if (depth < 8)
|
||||
png_set_packing (png);
|
||||
|
||||
/* convert grayscale to RGB */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
png_set_gray_to_rgb (png);
|
||||
}
|
||||
|
||||
if (interlace != PNG_INTERLACE_NONE)
|
||||
png_set_interlace_handling (png);
|
||||
|
||||
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
|
||||
|
||||
/* recheck header after setting EXPAND options */
|
||||
png_read_update_info (png, info);
|
||||
png_get_IHDR (png, info,
|
||||
&png_width, &png_height, &depth,
|
||||
&color_type, &interlace, NULL, NULL);
|
||||
if (depth != 8 ||
|
||||
! (color_type == PNG_COLOR_TYPE_RGB ||
|
||||
color_type == PNG_COLOR_TYPE_RGB_ALPHA))
|
||||
{
|
||||
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR));
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
switch (color_type) {
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
/* fall-through just in case ;-) */
|
||||
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
png_set_read_user_transform_fn (png, premultiply_data);
|
||||
break;
|
||||
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
png_set_read_user_transform_fn (png, convert_bytes_to_data);
|
||||
break;
|
||||
}
|
||||
|
||||
stride = cairo_format_stride_for_width (format, png_width);
|
||||
if (stride < 0) {
|
||||
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
data = _cairo_malloc_ab (png_height, stride);
|
||||
if (data == NULL) {
|
||||
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
|
||||
if (row_pointers == NULL) {
|
||||
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < png_height; i++)
|
||||
row_pointers[i] = &data[i * stride];
|
||||
|
||||
png_read_image (png, row_pointers);
|
||||
png_read_end (png, info);
|
||||
|
||||
if (status) { /* catch any late warnings - probably hit an error already */
|
||||
surface = _cairo_surface_create_in_error (status);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data, format,
|
||||
png_width, png_height,
|
||||
stride);
|
||||
if (surface->status)
|
||||
goto BAIL;
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
|
||||
data = NULL;
|
||||
|
||||
BAIL:
|
||||
if (row_pointers)
|
||||
free (row_pointers);
|
||||
if (data)
|
||||
free (data);
|
||||
if (png)
|
||||
png_destroy_read_struct (&png, &info, NULL);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_read_func (png_structp png, png_bytep data, png_size_t size)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = png_get_io_ptr (png);
|
||||
while (size) {
|
||||
size_t ret = fread (data, 1, size, fp);
|
||||
size -= ret;
|
||||
data += ret;
|
||||
if (size && (feof (fp) || ferror (fp))) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = _cairo_error (CAIRO_STATUS_READ_ERROR);
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_image_surface_create_from_png:
|
||||
* @filename: name of PNG file to load
|
||||
*
|
||||
* Creates a new image surface and initializes the contents to the
|
||||
* given PNG file.
|
||||
*
|
||||
* Return value: a new #cairo_surface_t initialized with the contents
|
||||
* of the PNG file, or a "nil" surface if any error occurred. A nil
|
||||
* surface can be checked for with cairo_surface_status(surface) which
|
||||
* may return one of the following values:
|
||||
*
|
||||
* %CAIRO_STATUS_NO_MEMORY
|
||||
* %CAIRO_STATUS_FILE_NOT_FOUND
|
||||
* %CAIRO_STATUS_READ_ERROR
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_image_surface_create_from_png (const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
fp = fopen (filename, "rb");
|
||||
if (fp == NULL) {
|
||||
cairo_status_t status;
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
case ENOENT:
|
||||
status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
|
||||
break;
|
||||
default:
|
||||
status = _cairo_error (CAIRO_STATUS_READ_ERROR);
|
||||
break;
|
||||
}
|
||||
return _cairo_surface_create_in_error (status);
|
||||
}
|
||||
|
||||
surface = read_png (stdio_read_func, fp);
|
||||
|
||||
fclose (fp);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
struct png_read_closure_t {
|
||||
cairo_read_func_t read_func;
|
||||
void *closure;
|
||||
};
|
||||
|
||||
static void
|
||||
stream_read_func (png_structp png, png_bytep data, png_size_t size)
|
||||
{
|
||||
cairo_status_t status;
|
||||
struct png_read_closure_t *png_closure;
|
||||
|
||||
png_closure = png_get_io_ptr (png);
|
||||
status = png_closure->read_func (png_closure->closure, data, size);
|
||||
if (status) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = status;
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_image_surface_create_from_png_stream:
|
||||
* @read_func: function called to read the data of the file
|
||||
* @closure: data to pass to @read_func.
|
||||
*
|
||||
* Creates a new image surface from PNG data read incrementally
|
||||
* via the @read_func function.
|
||||
*
|
||||
* Return value: a new #cairo_surface_t initialized with the contents
|
||||
* of the PNG file or %NULL if the data read is not a valid PNG image or
|
||||
* memory could not be allocated for the operation.
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
|
||||
void *closure)
|
||||
{
|
||||
struct png_read_closure_t png_closure;
|
||||
|
||||
png_closure.read_func = read_func;
|
||||
png_closure.closure = closure;
|
||||
|
||||
return read_png (stream_read_func, &png_closure);
|
||||
}
|
||||
149
uppdev/plugin/cairo/lib/cairo-polygon.c
Normal file
149
uppdev/plugin/cairo/lib/cairo-polygon.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
void
|
||||
_cairo_polygon_init (cairo_polygon_t *polygon)
|
||||
{
|
||||
polygon->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
polygon->num_edges = 0;
|
||||
|
||||
polygon->edges = polygon->edges_embedded;
|
||||
polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
|
||||
|
||||
polygon->has_current_point = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_polygon_fini (cairo_polygon_t *polygon)
|
||||
{
|
||||
if (polygon->edges != polygon->edges_embedded)
|
||||
free (polygon->edges);
|
||||
}
|
||||
|
||||
/* make room for at least one more edge */
|
||||
static cairo_bool_t
|
||||
_cairo_polygon_grow (cairo_polygon_t *polygon)
|
||||
{
|
||||
cairo_edge_t *new_edges;
|
||||
int old_size = polygon->edges_size;
|
||||
int new_size = 4 * old_size;
|
||||
|
||||
if (polygon->edges == polygon->edges_embedded) {
|
||||
new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t));
|
||||
if (new_edges != NULL)
|
||||
memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t));
|
||||
} else {
|
||||
new_edges = _cairo_realloc_ab (polygon->edges,
|
||||
new_size, sizeof (cairo_edge_t));
|
||||
}
|
||||
|
||||
if (new_edges == NULL) {
|
||||
polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
polygon->edges = new_edges;
|
||||
polygon->edges_size = new_size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon,
|
||||
const cairo_point_t *p1,
|
||||
const cairo_point_t *p2)
|
||||
{
|
||||
cairo_edge_t *edge;
|
||||
|
||||
/* drop horizontal edges */
|
||||
if (p1->y == p2->y)
|
||||
goto DONE;
|
||||
|
||||
if (polygon->num_edges == polygon->edges_size) {
|
||||
if (! _cairo_polygon_grow (polygon))
|
||||
return;
|
||||
}
|
||||
|
||||
edge = &polygon->edges[polygon->num_edges++];
|
||||
if (p1->y < p2->y) {
|
||||
edge->edge.p1 = *p1;
|
||||
edge->edge.p2 = *p2;
|
||||
edge->clockWise = 1;
|
||||
} else {
|
||||
edge->edge.p1 = *p2;
|
||||
edge->edge.p2 = *p1;
|
||||
edge->clockWise = 0;
|
||||
}
|
||||
|
||||
DONE:
|
||||
_cairo_polygon_move_to (polygon, p2);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_polygon_move_to (cairo_polygon_t *polygon,
|
||||
const cairo_point_t *point)
|
||||
{
|
||||
if (! polygon->has_current_point)
|
||||
polygon->first_point = *point;
|
||||
|
||||
polygon->current_point = *point;
|
||||
polygon->has_current_point = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_polygon_line_to (cairo_polygon_t *polygon,
|
||||
const cairo_point_t *point)
|
||||
{
|
||||
if (polygon->has_current_point)
|
||||
_cairo_polygon_add_edge (polygon, &polygon->current_point, point);
|
||||
else
|
||||
_cairo_polygon_move_to (polygon, point);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_polygon_close (cairo_polygon_t *polygon)
|
||||
{
|
||||
if (polygon->has_current_point) {
|
||||
_cairo_polygon_add_edge (polygon,
|
||||
&polygon->current_point,
|
||||
&polygon->first_point);
|
||||
|
||||
polygon->has_current_point = FALSE;
|
||||
}
|
||||
}
|
||||
57
uppdev/plugin/cairo/lib/cairo-private.h
Normal file
57
uppdev/plugin/cairo/lib/cairo-private.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PRIVATE_H
|
||||
#define CAIRO_PRIVATE_H
|
||||
|
||||
#include "cairo-reference-count-private.h"
|
||||
#include "cairo-gstate-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
struct _cairo {
|
||||
cairo_reference_count_t ref_count;
|
||||
|
||||
cairo_status_t status;
|
||||
|
||||
cairo_user_data_array_t user_data;
|
||||
|
||||
cairo_gstate_t *gstate;
|
||||
cairo_gstate_t gstate_tail[1];
|
||||
cairo_gstate_t *gstate_freelist;
|
||||
|
||||
cairo_path_fixed_t path[1];
|
||||
};
|
||||
|
||||
#endif /* CAIRO_PRIVATE_H */
|
||||
100
uppdev/plugin/cairo/lib/cairo-ps-surface-private.h
Normal file
100
uppdev/plugin/cairo/lib/cairo-ps-surface-private.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PS_SURFACE_PRIVATE_H
|
||||
#define CAIRO_PS_SURFACE_PRIVATE_H
|
||||
|
||||
#include "cairo-ps.h"
|
||||
|
||||
#include "cairo-surface-private.h"
|
||||
#include "cairo-pdf-operators-private.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct cairo_ps_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* Here final_stream corresponds to the stream/file passed to
|
||||
* cairo_ps_surface_create surface is built. Meanwhile stream is a
|
||||
* temporary stream in which the file output is built, (so that
|
||||
* the header can be built and inserted into the target stream
|
||||
* before the contents of the temporary stream are copied). */
|
||||
cairo_output_stream_t *final_stream;
|
||||
|
||||
FILE *tmpfile;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
cairo_bool_t eps;
|
||||
cairo_content_t content;
|
||||
double width;
|
||||
double height;
|
||||
int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
|
||||
cairo_matrix_t cairo_to_ps;
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
cairo_bool_t use_string_datasource;
|
||||
|
||||
cairo_bool_t current_pattern_is_solid_color;
|
||||
cairo_color_t current_color;
|
||||
|
||||
int num_pages;
|
||||
|
||||
cairo_paginated_mode_t paginated_mode;
|
||||
|
||||
cairo_bool_t force_fallbacks;
|
||||
cairo_bool_t has_creation_date;
|
||||
time_t creation_date;
|
||||
|
||||
cairo_scaled_font_subsets_t *font_subsets;
|
||||
|
||||
cairo_array_t dsc_header_comments;
|
||||
cairo_array_t dsc_setup_comments;
|
||||
cairo_array_t dsc_page_setup_comments;
|
||||
|
||||
cairo_array_t *dsc_comment_target;
|
||||
|
||||
cairo_ps_level_t ps_level;
|
||||
cairo_ps_level_t ps_level_used;
|
||||
|
||||
cairo_pdf_operators_t pdf_operators;
|
||||
cairo_surface_t *paginated_surface;
|
||||
} cairo_ps_surface_t;
|
||||
|
||||
#endif /* CAIRO_PS_SURFACE_PRIVATE_H */
|
||||
3337
uppdev/plugin/cairo/lib/cairo-ps-surface.c
Normal file
3337
uppdev/plugin/cairo/lib/cairo-ps-surface.c
Normal file
File diff suppressed because it is too large
Load diff
114
uppdev/plugin/cairo/lib/cairo-ps.h
Normal file
114
uppdev/plugin/cairo/lib/cairo-ps.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PS_H
|
||||
#define CAIRO_PS_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_PS_SURFACE
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
/* PS-surface functions */
|
||||
|
||||
/**
|
||||
* cairo_ps_level_t:
|
||||
* @CAIRO_PS_LEVEL_2: The language level 2 of the PostScript specification.
|
||||
* @CAIRO_PS_LEVEL_3: The language level 3 of the PostScript specification.
|
||||
*
|
||||
* #cairo_ps_level_t is used to describe the language level of the
|
||||
* PostScript Language Reference that a generated PostScript file will
|
||||
* conform to.
|
||||
*/
|
||||
typedef enum _cairo_ps_level {
|
||||
CAIRO_PS_LEVEL_2,
|
||||
CAIRO_PS_LEVEL_3
|
||||
} cairo_ps_level_t;
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_ps_surface_create (const char *filename,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
void *closure,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_restrict_to_level (cairo_surface_t *surface,
|
||||
cairo_ps_level_t level);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_get_levels (cairo_ps_level_t const **levels,
|
||||
int *num_levels);
|
||||
|
||||
cairo_public const char *
|
||||
cairo_ps_level_to_string (cairo_ps_level_t level);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_set_eps (cairo_surface_t *surface,
|
||||
cairo_bool_t eps);
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_ps_surface_get_eps (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_set_size (cairo_surface_t *surface,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_dsc_comment (cairo_surface_t *surface,
|
||||
const char *comment);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_PS_SURFACE */
|
||||
# error Cairo was not compiled with support for the ps backend
|
||||
#endif /* CAIRO_HAS_PS_SURFACE */
|
||||
|
||||
#endif /* CAIRO_PS_H */
|
||||
840
uppdev/plugin/cairo/lib/cairo-quartz-font.c
Normal file
840
uppdev/plugin/cairo/lib/cairo-quartz-font.c
Normal file
|
|
@ -0,0 +1,840 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright <EFBFBD> 2008 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "cairo-quartz.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
/* CreateWithFontName exists in 10.5, but not in 10.4; CreateWithName isn't public in 10.4 */
|
||||
static CGFontRef (*CGFontCreateWithFontNamePtr) (CFStringRef) = NULL;
|
||||
static CGFontRef (*CGFontCreateWithNamePtr) (const char *) = NULL;
|
||||
|
||||
/* These aren't public before 10.5, and some have different names in 10.4 */
|
||||
static int (*CGFontGetUnitsPerEmPtr) (CGFontRef) = NULL;
|
||||
static bool (*CGFontGetGlyphAdvancesPtr) (CGFontRef, const CGGlyph[], size_t, int[]) = NULL;
|
||||
static bool (*CGFontGetGlyphBBoxesPtr) (CGFontRef, const CGGlyph[], size_t, CGRect[]) = NULL;
|
||||
static CGRect (*CGFontGetFontBBoxPtr) (CGFontRef) = NULL;
|
||||
|
||||
/* Not public, but present */
|
||||
static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const CGGlyph[], size_t) = NULL;
|
||||
|
||||
/* Not public in the least bit */
|
||||
static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL;
|
||||
|
||||
/* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */
|
||||
typedef struct {
|
||||
int ascent;
|
||||
int descent;
|
||||
int leading;
|
||||
} quartz_CGFontMetrics;
|
||||
static quartz_CGFontMetrics* (*CGFontGetHMetricsPtr) (CGFontRef fontRef) = NULL;
|
||||
static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL;
|
||||
static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL;
|
||||
static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL;
|
||||
|
||||
static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
|
||||
static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE;
|
||||
|
||||
static void
|
||||
quartz_font_ensure_symbols(void)
|
||||
{
|
||||
if (_cairo_quartz_font_symbol_lookup_done)
|
||||
return;
|
||||
|
||||
/* Look for the 10.5 versions first */
|
||||
CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBBoxes");
|
||||
if (!CGFontGetGlyphBBoxesPtr)
|
||||
CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBoundingBoxes");
|
||||
|
||||
CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnichars");
|
||||
if (!CGFontGetGlyphsForUnicharsPtr)
|
||||
CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes");
|
||||
|
||||
CGFontGetFontBBoxPtr = dlsym(RTLD_DEFAULT, "CGFontGetFontBBox");
|
||||
|
||||
/* We just need one of these two */
|
||||
CGFontCreateWithFontNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithFontName");
|
||||
CGFontCreateWithNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithName");
|
||||
|
||||
/* These have the same name in 10.4 and 10.5 */
|
||||
CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm");
|
||||
CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances");
|
||||
CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
|
||||
|
||||
CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics");
|
||||
CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent");
|
||||
CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent");
|
||||
CGFontGetLeadingPtr = dlsym(RTLD_DEFAULT, "CGFontGetLeading");
|
||||
|
||||
if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
|
||||
CGFontGetGlyphBBoxesPtr &&
|
||||
CGFontGetGlyphsForUnicharsPtr &&
|
||||
CGFontGetUnitsPerEmPtr &&
|
||||
CGFontGetGlyphAdvancesPtr &&
|
||||
CGFontGetGlyphPathPtr &&
|
||||
(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
|
||||
_cairo_quartz_font_symbols_present = TRUE;
|
||||
|
||||
_cairo_quartz_font_symbol_lookup_done = TRUE;
|
||||
}
|
||||
|
||||
typedef struct _cairo_quartz_font_face cairo_quartz_font_face_t;
|
||||
typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t;
|
||||
|
||||
struct _cairo_quartz_scaled_font {
|
||||
cairo_scaled_font_t base;
|
||||
};
|
||||
|
||||
struct _cairo_quartz_font_face {
|
||||
cairo_font_face_t base;
|
||||
|
||||
CGFontRef cgFont;
|
||||
};
|
||||
|
||||
/*
|
||||
* font face backend
|
||||
*/
|
||||
|
||||
static void
|
||||
_cairo_quartz_font_face_destroy (void *abstract_face)
|
||||
{
|
||||
cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
|
||||
|
||||
CGFontRelease (font_face->cgFont);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_font_face_scaled_font_create (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_quartz_font_face_t *font_face = abstract_face;
|
||||
cairo_quartz_scaled_font_t *font = NULL;
|
||||
cairo_status_t status;
|
||||
cairo_font_extents_t fs_metrics;
|
||||
double ems;
|
||||
CGRect bbox;
|
||||
|
||||
quartz_font_ensure_symbols();
|
||||
if (!_cairo_quartz_font_symbols_present)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font = malloc(sizeof(cairo_quartz_scaled_font_t));
|
||||
if (font == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memset (font, 0, sizeof(cairo_quartz_scaled_font_t));
|
||||
|
||||
status = _cairo_scaled_font_init (&font->base,
|
||||
&font_face->base, font_matrix, ctm, options,
|
||||
&_cairo_quartz_scaled_font_backend);
|
||||
if (status)
|
||||
goto FINISH;
|
||||
|
||||
ems = CGFontGetUnitsPerEmPtr (font_face->cgFont);
|
||||
|
||||
/* initialize metrics */
|
||||
if (CGFontGetFontBBoxPtr && CGFontGetAscentPtr) {
|
||||
fs_metrics.ascent = (CGFontGetAscentPtr (font_face->cgFont) / ems);
|
||||
fs_metrics.descent = - (CGFontGetDescentPtr (font_face->cgFont) / ems);
|
||||
fs_metrics.height = fs_metrics.ascent + fs_metrics.descent +
|
||||
(CGFontGetLeadingPtr (font_face->cgFont) / ems);
|
||||
|
||||
bbox = CGFontGetFontBBoxPtr (font_face->cgFont);
|
||||
fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
|
||||
fs_metrics.max_y_advance = 0.0;
|
||||
} else {
|
||||
CGGlyph wGlyph;
|
||||
UniChar u;
|
||||
|
||||
quartz_CGFontMetrics *m;
|
||||
m = CGFontGetHMetricsPtr (font_face->cgFont);
|
||||
|
||||
/* On OX 10.4, GetHMetricsPtr sometimes returns NULL for unknown reasons */
|
||||
if (!m) {
|
||||
status = _cairo_error(CAIRO_STATUS_NULL_POINTER);
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
fs_metrics.ascent = (m->ascent / ems);
|
||||
fs_metrics.descent = - (m->descent / ems);
|
||||
fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems);
|
||||
|
||||
/* We kind of have to guess here; W's big, right? */
|
||||
u = (UniChar) 'W';
|
||||
CGFontGetGlyphsForUnicharsPtr (font_face->cgFont, &u, &wGlyph, 1);
|
||||
if (wGlyph && CGFontGetGlyphBBoxesPtr (font_face->cgFont, &wGlyph, 1, &bbox)) {
|
||||
fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
|
||||
fs_metrics.max_y_advance = 0.0;
|
||||
} else {
|
||||
fs_metrics.max_x_advance = 0.0;
|
||||
fs_metrics.max_y_advance = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_scaled_font_set_metrics (&font->base, &fs_metrics);
|
||||
|
||||
FINISH:
|
||||
if (status != CAIRO_STATUS_SUCCESS) {
|
||||
free (font);
|
||||
} else {
|
||||
*font_out = (cairo_scaled_font_t*) font;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
|
||||
CAIRO_FONT_TYPE_QUARTZ,
|
||||
_cairo_quartz_font_face_destroy,
|
||||
NULL, /* direct implementation */
|
||||
_cairo_quartz_font_face_scaled_font_create
|
||||
};
|
||||
|
||||
/**
|
||||
* cairo_quartz_font_face_create_for_cgfont
|
||||
* @font: a #CGFontRef obtained through a method external to cairo.
|
||||
*
|
||||
* Creates a new font for the Quartz font backend based on a
|
||||
* #CGFontRef. This font can then be used with
|
||||
* cairo_set_font_face() or cairo_scaled_font_create().
|
||||
*
|
||||
* Return value: a newly created #cairo_font_face_t. Free with
|
||||
* cairo_font_face_destroy() when you are done using it.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
cairo_font_face_t *
|
||||
cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
|
||||
{
|
||||
cairo_quartz_font_face_t *font_face;
|
||||
|
||||
quartz_font_ensure_symbols();
|
||||
|
||||
font_face = malloc (sizeof (cairo_quartz_font_face_t));
|
||||
if (!font_face) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
font_face->cgFont = CGFontRetain (font);
|
||||
|
||||
_cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
|
||||
|
||||
return &font_face->base;
|
||||
}
|
||||
|
||||
/*
|
||||
* scaled font backend
|
||||
*/
|
||||
|
||||
static cairo_quartz_font_face_t *
|
||||
_cairo_quartz_scaled_to_face (void *abstract_font)
|
||||
{
|
||||
cairo_quartz_scaled_font_t *sfont = (cairo_quartz_scaled_font_t*) abstract_font;
|
||||
cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (&sfont->base);
|
||||
if (!font_face || font_face->backend->type != CAIRO_FONT_TYPE_QUARTZ)
|
||||
return NULL;
|
||||
|
||||
return (cairo_quartz_font_face_t*) font_face;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_font_get_implementation (cairo_toy_font_face_t *toy_face,
|
||||
cairo_scaled_font_t **font_face_out)
|
||||
{
|
||||
static cairo_user_data_key_t impl_font_face_key;
|
||||
cairo_font_face_t *face;
|
||||
cairo_status_t status;
|
||||
const char *family = toy_face->family;
|
||||
char *full_name = malloc(strlen(family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
|
||||
CFStringRef cgFontName = NULL;
|
||||
CGFontRef cgFont = NULL;
|
||||
int loop;
|
||||
|
||||
face = cairo_font_face_get_user_data (&toy_face->base,
|
||||
&impl_font_face_key);
|
||||
if (face) {
|
||||
*font_face_out = face;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
quartz_font_ensure_symbols();
|
||||
if (! _cairo_quartz_font_symbols_present)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/* handle CSS-ish faces */
|
||||
if (!strcmp(family, "serif") || !strcmp(family, "Times Roman"))
|
||||
family = "Times";
|
||||
else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans"))
|
||||
family = "Helvetica";
|
||||
else if (!strcmp(family, "cursive"))
|
||||
family = "Apple Chancery";
|
||||
else if (!strcmp(family, "fantasy"))
|
||||
family = "Papyrus";
|
||||
else if (!strcmp(family, "monospace") || !strcmp(family, "mono"))
|
||||
family = "Courier";
|
||||
|
||||
/* Try to build up the full name, e.g. "Helvetica Bold Oblique" first,
|
||||
* then drop the bold, then drop the slant, then drop both.. finally
|
||||
* just use "Helvetica". And if Helvetica doesn't exist, give up.
|
||||
*/
|
||||
for (loop = 0; loop < 5; loop++) {
|
||||
if (loop == 4)
|
||||
family = "Helvetica";
|
||||
|
||||
strcpy (full_name, family);
|
||||
|
||||
if (loop < 3 && (loop & 1) == 0) {
|
||||
if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
|
||||
strcat (full_name, " Bold");
|
||||
}
|
||||
|
||||
if (loop < 3 && (loop & 2) == 0) {
|
||||
if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
|
||||
strcat (full_name, " Italic");
|
||||
else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
|
||||
strcat (full_name, " Oblique");
|
||||
}
|
||||
|
||||
if (CGFontCreateWithFontNamePtr) {
|
||||
cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
|
||||
cgFont = CGFontCreateWithFontNamePtr (cgFontName);
|
||||
CFRelease (cgFontName);
|
||||
} else {
|
||||
cgFont = CGFontCreateWithNamePtr (full_name);
|
||||
}
|
||||
|
||||
if (cgFont)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cgFont) {
|
||||
/* Give up */
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
face = cairo_quartz_font_face_create_for_cgfont (cgFont);
|
||||
CGFontRelease (cgFont);
|
||||
|
||||
if (face->status)
|
||||
return face->status;
|
||||
|
||||
status = cairo_font_face_set_user_data (&toy_face->base,
|
||||
&impl_font_face_key,
|
||||
face,
|
||||
(cairo_destroy_func_t) cairo_font_face_destroy);
|
||||
|
||||
if (status) {
|
||||
cairo_font_face_destroy (face);
|
||||
return status;
|
||||
}
|
||||
|
||||
*font_face_out = face;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_font_face_t *face;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_quartz_font_get_implementation (toy_face, &face);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_quartz_font_face_scaled_font_create (face,
|
||||
font_matrix, ctm,
|
||||
options,
|
||||
&scaled_font);
|
||||
cairo_font_face_destroy (face);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
*font_out = scaled_font;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_quartz_font_fini(void *abstract_font)
|
||||
{
|
||||
}
|
||||
|
||||
#define INVALID_GLYPH 0x00
|
||||
|
||||
static inline CGGlyph
|
||||
_cairo_quartz_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
|
||||
unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
|
||||
if (index > 0xffff)
|
||||
return INVALID_GLYPH;
|
||||
return (CGGlyph) index;
|
||||
}
|
||||
|
||||
static inline cairo_status_t
|
||||
_cairo_matrix_to_unit_quartz_matrix (const cairo_matrix_t *m, CGAffineTransform *txout,
|
||||
double *xout, double *yout)
|
||||
{
|
||||
CGAffineTransform transform;
|
||||
double xscale, yscale;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_matrix_compute_basis_scale_factors (m, &xscale, &yscale, 1);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
transform = CGAffineTransformMake (m->xx, - m->yx,
|
||||
- m->xy, m->yy,
|
||||
0.0f, 0.0f);
|
||||
if (xout)
|
||||
*xout = xscale;
|
||||
if (yout)
|
||||
*yout = yscale;
|
||||
|
||||
if (xscale)
|
||||
xscale = 1.0 / xscale;
|
||||
if (yscale)
|
||||
yscale = 1.0 / yscale;
|
||||
|
||||
*txout = CGAffineTransformScale (transform, xscale, yscale);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
|
||||
cairo_scaled_glyph_t *scaled_glyph)
|
||||
{
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
|
||||
cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
|
||||
CGAffineTransform textMatrix;
|
||||
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
|
||||
int advance;
|
||||
CGRect bbox;
|
||||
double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
|
||||
double xscale, yscale;
|
||||
double xmin, ymin, xmax, ymax;
|
||||
|
||||
if (glyph == INVALID_GLYPH)
|
||||
goto FAIL;
|
||||
|
||||
if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
|
||||
!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
|
||||
goto FAIL;
|
||||
|
||||
status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
|
||||
&xscale, &yscale, 1);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
bbox = CGRectMake (bbox.origin.x / emscale,
|
||||
bbox.origin.y / emscale,
|
||||
bbox.size.width / emscale,
|
||||
bbox.size.height / emscale);
|
||||
|
||||
/* Should we want to always integer-align glyph extents, we can do so in this way */
|
||||
#if 0
|
||||
{
|
||||
CGAffineTransform textMatrix;
|
||||
textMatrix = CGAffineTransformMake (font->base.scale.xx,
|
||||
-font->base.scale.yx,
|
||||
-font->base.scale.xy,
|
||||
font->base.scale.yy,
|
||||
0.0f, 0.0f);
|
||||
|
||||
bbox = CGRectApplyAffineTransform (bbox, textMatrix);
|
||||
bbox = CGRectIntegral (bbox);
|
||||
bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
|
||||
bbox.origin.x / emscale, bbox.origin.y / emscale,
|
||||
bbox.size.width / emscale, bbox.size.height / emscale);
|
||||
#endif
|
||||
|
||||
xmin = CGRectGetMinX(bbox);
|
||||
ymin = CGRectGetMinY(bbox);
|
||||
xmax = CGRectGetMaxX(bbox);
|
||||
ymax = CGRectGetMaxY(bbox);
|
||||
|
||||
extents.x_bearing = xmin;
|
||||
extents.y_bearing = - ymax;
|
||||
extents.width = xmax - xmin;
|
||||
extents.height = ymax - ymin;
|
||||
|
||||
extents.x_advance = (double) advance / emscale;
|
||||
extents.y_advance = 0.0;
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
|
||||
extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
|
||||
#endif
|
||||
|
||||
FAIL:
|
||||
_cairo_scaled_glyph_set_metrics (scaled_glyph,
|
||||
&font->base,
|
||||
&extents);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_quartz_path_apply_func (void *info, const CGPathElement *el)
|
||||
{
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) info;
|
||||
|
||||
switch (el->type) {
|
||||
case kCGPathElementMoveToPoint:
|
||||
_cairo_path_fixed_move_to (path,
|
||||
_cairo_fixed_from_double(el->points[0].x),
|
||||
_cairo_fixed_from_double(el->points[0].y));
|
||||
break;
|
||||
case kCGPathElementAddLineToPoint:
|
||||
_cairo_path_fixed_line_to (path,
|
||||
_cairo_fixed_from_double(el->points[0].x),
|
||||
_cairo_fixed_from_double(el->points[0].y));
|
||||
break;
|
||||
case kCGPathElementAddQuadCurveToPoint: {
|
||||
cairo_fixed_t fx, fy;
|
||||
double x, y;
|
||||
if (!_cairo_path_fixed_get_current_point (path, &fx, &fy))
|
||||
fx = fy = 0;
|
||||
x = _cairo_fixed_to_double (fx);
|
||||
y = _cairo_fixed_to_double (fy);
|
||||
|
||||
_cairo_path_fixed_curve_to (path,
|
||||
_cairo_fixed_from_double((x + el->points[0].x * 2.0) / 3.0),
|
||||
_cairo_fixed_from_double((y + el->points[0].y * 2.0) / 3.0),
|
||||
_cairo_fixed_from_double((el->points[0].x * 2.0 + el->points[1].x) / 3.0),
|
||||
_cairo_fixed_from_double((el->points[0].y * 2.0 + el->points[1].y) / 3.0),
|
||||
_cairo_fixed_from_double(el->points[1].x),
|
||||
_cairo_fixed_from_double(el->points[1].y));
|
||||
}
|
||||
break;
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
_cairo_path_fixed_curve_to (path,
|
||||
_cairo_fixed_from_double(el->points[0].x),
|
||||
_cairo_fixed_from_double(el->points[0].y),
|
||||
_cairo_fixed_from_double(el->points[1].x),
|
||||
_cairo_fixed_from_double(el->points[1].y),
|
||||
_cairo_fixed_from_double(el->points[2].x),
|
||||
_cairo_fixed_from_double(el->points[2].y));
|
||||
break;
|
||||
case kCGPathElementCloseSubpath:
|
||||
_cairo_path_fixed_close_path (path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
|
||||
cairo_scaled_glyph_t *scaled_glyph)
|
||||
{
|
||||
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
|
||||
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
|
||||
CGAffineTransform textMatrix;
|
||||
CGPathRef glyphPath;
|
||||
cairo_path_fixed_t *path;
|
||||
|
||||
if (glyph == INVALID_GLYPH) {
|
||||
_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
textMatrix = CGAffineTransformMake (font->base.scale.xx,
|
||||
-font->base.scale.yx,
|
||||
-font->base.scale.xy,
|
||||
font->base.scale.yy,
|
||||
font->base.scale.x0,
|
||||
font->base.scale.y0);
|
||||
|
||||
textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0));
|
||||
|
||||
glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
|
||||
if (!glyphPath)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
path = _cairo_path_fixed_create ();
|
||||
if (!path) {
|
||||
CGPathRelease (glyphPath);
|
||||
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func);
|
||||
|
||||
CGPathRelease (glyphPath);
|
||||
|
||||
_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
|
||||
cairo_scaled_glyph_t *scaled_glyph)
|
||||
{
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
|
||||
|
||||
cairo_image_surface_t *surface = NULL;
|
||||
|
||||
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
|
||||
|
||||
int advance;
|
||||
CGRect bbox;
|
||||
double width, height;
|
||||
double xscale, yscale;
|
||||
double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
|
||||
|
||||
CGColorSpaceRef gray;
|
||||
CGContextRef cgContext = NULL;
|
||||
CGAffineTransform textMatrix;
|
||||
CGRect glyphRect, glyphRectInt;
|
||||
CGPoint glyphOrigin;
|
||||
|
||||
//fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);
|
||||
|
||||
/* Create blank 2x2 image if we don't have this character.
|
||||
* Maybe we should draw a better missing-glyph slug or something,
|
||||
* but this is ok for now.
|
||||
*/
|
||||
if (glyph == INVALID_GLYPH) {
|
||||
surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
|
||||
status = cairo_surface_status ((cairo_surface_t *) surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_scaled_glyph_set_surface (scaled_glyph,
|
||||
&font->base,
|
||||
surface);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
|
||||
!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
|
||||
{
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
|
||||
&xscale, &yscale, 1);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
textMatrix = CGAffineTransformMake (font->base.scale.xx,
|
||||
-font->base.scale.yx,
|
||||
-font->base.scale.xy,
|
||||
font->base.scale.yy,
|
||||
0.0f, 0.0f);
|
||||
glyphRect = CGRectMake (bbox.origin.x / emscale,
|
||||
bbox.origin.y / emscale,
|
||||
bbox.size.width / emscale,
|
||||
bbox.size.height / emscale);
|
||||
|
||||
glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);
|
||||
|
||||
/* Round the rectangle outwards, so that we don't have to deal
|
||||
* with non-integer-pixel origins or dimensions.
|
||||
*/
|
||||
glyphRectInt = CGRectIntegral (glyphRect);
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
|
||||
glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
|
||||
fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
|
||||
glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
|
||||
#endif
|
||||
|
||||
glyphOrigin = glyphRectInt.origin;
|
||||
|
||||
//textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));
|
||||
|
||||
width = glyphRectInt.size.width;
|
||||
height = glyphRectInt.size.height;
|
||||
|
||||
//fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
|
||||
|
||||
surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
|
||||
if (surface->base.status)
|
||||
return surface->base.status;
|
||||
|
||||
gray = CGColorSpaceCreateDeviceGray ();
|
||||
cgContext = CGBitmapContextCreate (surface->data,
|
||||
surface->width,
|
||||
surface->height,
|
||||
8,
|
||||
surface->stride,
|
||||
gray,
|
||||
kCGImageAlphaNone);
|
||||
CGColorSpaceRelease (gray);
|
||||
|
||||
CGContextSetFont (cgContext, font_face->cgFont);
|
||||
CGContextSetFontSize (cgContext, 1.0);
|
||||
CGContextSetTextMatrix (cgContext, textMatrix);
|
||||
|
||||
CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));
|
||||
|
||||
if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
|
||||
CGContextSetShouldAntialias (cgContext, false);
|
||||
|
||||
CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
|
||||
CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);
|
||||
|
||||
CGContextRelease (cgContext);
|
||||
|
||||
cairo_surface_set_device_offset (&surface->base,
|
||||
- glyphOrigin.x,
|
||||
height + glyphOrigin.y);
|
||||
|
||||
_cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_font_scaled_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info)
|
||||
{
|
||||
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font;
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (!status && (info & CAIRO_SCALED_GLYPH_INFO_METRICS))
|
||||
status = _cairo_quartz_init_glyph_metrics (font, scaled_glyph);
|
||||
|
||||
if (!status && (info & CAIRO_SCALED_GLYPH_INFO_PATH))
|
||||
status = _cairo_quartz_init_glyph_path (font, scaled_glyph);
|
||||
|
||||
if (!status && (info & CAIRO_SCALED_GLYPH_INFO_SURFACE))
|
||||
status = _cairo_quartz_init_glyph_surface (font, scaled_glyph);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
_cairo_quartz_ucs4_to_index (void *abstract_font,
|
||||
uint32_t ucs4)
|
||||
{
|
||||
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
|
||||
cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
|
||||
UniChar u = (UniChar) ucs4;
|
||||
CGGlyph glyph;
|
||||
|
||||
CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, &u, &glyph, 1);
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend = {
|
||||
CAIRO_FONT_TYPE_QUARTZ,
|
||||
_cairo_quartz_font_get_implementation,
|
||||
_cairo_quartz_font_create_toy,
|
||||
_cairo_quartz_font_fini,
|
||||
_cairo_quartz_font_scaled_glyph_init,
|
||||
NULL, /* text_to_glyphs */
|
||||
_cairo_quartz_ucs4_to_index,
|
||||
NULL, /* show_glyphs */
|
||||
NULL, /* load_truetype_table */
|
||||
NULL, /* map_glyphs_to_unicode */
|
||||
};
|
||||
|
||||
/*
|
||||
* private methods that the quartz surface uses
|
||||
*/
|
||||
|
||||
CGFontRef
|
||||
_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
|
||||
{
|
||||
cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font);
|
||||
|
||||
return ffont->cgFont;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* compat with old ATSUI backend
|
||||
*/
|
||||
|
||||
/**
|
||||
* cairo_quartz_font_face_create_for_atsu_font_id
|
||||
* @font_id: an ATSUFontID for the font.
|
||||
*
|
||||
* Creates a new font for the Quartz font backend based on an
|
||||
* #ATSUFontID. This font can then be used with
|
||||
* cairo_set_font_face() or cairo_scaled_font_create().
|
||||
*
|
||||
* Return value: a newly created #cairo_font_face_t. Free with
|
||||
* cairo_font_face_destroy() when you are done using it.
|
||||
*
|
||||
* Since: 1.6
|
||||
**/
|
||||
cairo_font_face_t *
|
||||
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id)
|
||||
{
|
||||
ATSFontRef atsFont = FMGetATSFontRefFromFont (font_id);
|
||||
CGFontRef cgFont = CGFontCreateWithPlatformFont (&atsFont);
|
||||
cairo_font_face_t *ff;
|
||||
|
||||
ff = cairo_quartz_font_face_create_for_cgfont (cgFont);
|
||||
|
||||
CGFontRelease (cgFont);
|
||||
|
||||
return ff;
|
||||
}
|
||||
|
||||
/* This is the old name for the above function, exported for compat purposes */
|
||||
cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
|
||||
|
||||
cairo_font_face_t *
|
||||
cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
|
||||
{
|
||||
return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
|
||||
}
|
||||
286
uppdev/plugin/cairo/lib/cairo-quartz-image-surface.c
Normal file
286
uppdev/plugin/cairo/lib/cairo-quartz-image-surface.c
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright <EFBFBD> 2008 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-quartz-image.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
#define SURFACE_ERROR_NO_MEMORY (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY)))
|
||||
#define SURFACE_ERROR_TYPE_MISMATCH (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_SURFACE_TYPE_MISMATCH)))
|
||||
#define SURFACE_ERROR_INVALID_FORMAT (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_FORMAT)))
|
||||
|
||||
static void
|
||||
DataProviderReleaseCallback (void *info, const void *data, size_t size)
|
||||
{
|
||||
cairo_surface_t *surface = (cairo_surface_t *) info;
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_quartz_image_surface_create_similar (void *asurface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *result;
|
||||
cairo_surface_t *isurf = cairo_image_surface_create (_cairo_format_from_content (content),
|
||||
width,
|
||||
height);
|
||||
if (cairo_surface_status(isurf))
|
||||
return isurf;
|
||||
|
||||
result = cairo_quartz_image_surface_create (isurf);
|
||||
cairo_surface_destroy (isurf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_image_surface_finish (void *asurface)
|
||||
{
|
||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
||||
|
||||
/* the imageSurface will be destroyed by the data provider's release callback */
|
||||
CGImageRelease (surface->image);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_image_surface_acquire_source_image (void *asurface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
||||
|
||||
*image_out = surface->imageSurface;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_image_surface_acquire_dest_image (void *asurface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
||||
|
||||
*image_out = surface->imageSurface;
|
||||
*image_rect = surface->extents;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_image_surface_get_extents (void *asurface,
|
||||
cairo_rectangle_int_t *extents)
|
||||
{
|
||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
||||
|
||||
*extents = surface->extents;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* we assume some drawing happened to the image buffer; make sure it's
|
||||
* represented in the CGImage on flush()
|
||||
*/
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_image_surface_flush (void *asurface)
|
||||
{
|
||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
||||
CGImageRef oldImage = surface->image;
|
||||
CGImageRef newImage = NULL;
|
||||
|
||||
/* To be released by the ReleaseCallback */
|
||||
cairo_surface_reference ((cairo_surface_t*) surface->imageSurface);
|
||||
|
||||
newImage = _cairo_quartz_create_cgimage (surface->imageSurface->format,
|
||||
surface->imageSurface->width,
|
||||
surface->imageSurface->height,
|
||||
surface->imageSurface->stride,
|
||||
surface->imageSurface->data,
|
||||
TRUE,
|
||||
NULL,
|
||||
DataProviderReleaseCallback,
|
||||
surface->imageSurface);
|
||||
|
||||
surface->image = newImage;
|
||||
CGImageRelease (oldImage);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_quartz_image_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_QUARTZ_IMAGE,
|
||||
_cairo_quartz_image_surface_create_similar,
|
||||
_cairo_quartz_image_surface_finish,
|
||||
_cairo_quartz_image_surface_acquire_source_image,
|
||||
NULL, /* release_source_image */
|
||||
_cairo_quartz_image_surface_acquire_dest_image,
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_quartz_image_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
_cairo_quartz_image_surface_flush,
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
|
||||
NULL, /* paint */
|
||||
NULL, /* mask */
|
||||
NULL, /* stroke */
|
||||
NULL, /* fill */
|
||||
NULL, /* surface_show_glyphs */
|
||||
NULL, /* snapshot */
|
||||
NULL, /* is_similar */
|
||||
NULL, /* reset */
|
||||
NULL /* fill_stroke */
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* cairo_quartz_image_surface_create
|
||||
* @surface: a cairo image surface to wrap with a quartz image surface
|
||||
*
|
||||
* Creates a Quartz surface backed by a CGImageRef that references the
|
||||
* given image surface. The resulting surface can be rendered quickly
|
||||
* when used as a source when rendering to a #cairo_quartz_surface. If
|
||||
* the data in the image surface is ever updated, cairo_surface_flush()
|
||||
* must be called on the #cairo_quartz_image_surface to ensure that the
|
||||
* CGImageRef refers to the updated data.
|
||||
*
|
||||
* Return value: the newly created surface.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
cairo_surface_t *
|
||||
cairo_quartz_image_surface_create (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_quartz_image_surface_t *qisurf;
|
||||
|
||||
CGImageRef image;
|
||||
|
||||
cairo_image_surface_t *image_surface;
|
||||
int width, height, stride;
|
||||
cairo_format_t format;
|
||||
unsigned char *data;
|
||||
|
||||
if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_IMAGE)
|
||||
return SURFACE_ERROR_TYPE_MISMATCH;
|
||||
|
||||
image_surface = (cairo_image_surface_t*) surface;
|
||||
width = image_surface->width;
|
||||
height = image_surface->height;
|
||||
stride = image_surface->stride;
|
||||
format = image_surface->format;
|
||||
data = image_surface->data;
|
||||
|
||||
if (!_cairo_quartz_verify_surface_size(width, height))
|
||||
return SURFACE_ERROR_NO_MEMORY;
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return SURFACE_ERROR_NO_MEMORY;
|
||||
|
||||
if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24)
|
||||
return SURFACE_ERROR_INVALID_FORMAT;
|
||||
|
||||
qisurf = malloc(sizeof(cairo_quartz_image_surface_t));
|
||||
if (qisurf == NULL)
|
||||
return SURFACE_ERROR_NO_MEMORY;
|
||||
|
||||
memset (qisurf, 0, sizeof(cairo_quartz_image_surface_t));
|
||||
|
||||
/* In case the create_cgimage fails, this ref will
|
||||
* be released via the callback (which will be called in
|
||||
* case of failure.)
|
||||
*/
|
||||
cairo_surface_reference (surface);
|
||||
|
||||
image = _cairo_quartz_create_cgimage (format,
|
||||
width, height,
|
||||
stride,
|
||||
data,
|
||||
TRUE,
|
||||
NULL,
|
||||
DataProviderReleaseCallback,
|
||||
image_surface);
|
||||
|
||||
if (!image) {
|
||||
free (qisurf);
|
||||
return SURFACE_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&qisurf->base,
|
||||
&cairo_quartz_image_surface_backend,
|
||||
_cairo_content_from_format (format));
|
||||
|
||||
qisurf->extents.x = qisurf->extents.y = 0;
|
||||
qisurf->extents.width = width;
|
||||
qisurf->extents.height = height;
|
||||
|
||||
qisurf->image = image;
|
||||
qisurf->imageSurface = image_surface;
|
||||
|
||||
return &qisurf->base;
|
||||
}
|
||||
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_quartz_image_surface_get_image (cairo_surface_t *asurface)
|
||||
{
|
||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t*) asurface;
|
||||
|
||||
if (cairo_surface_get_type(asurface) != CAIRO_SURFACE_TYPE_QUARTZ_IMAGE)
|
||||
return NULL;
|
||||
|
||||
return (cairo_surface_t*) surface->imageSurface;
|
||||
}
|
||||
59
uppdev/plugin/cairo/lib/cairo-quartz-image.h
Normal file
59
uppdev/plugin/cairo/lib/cairo-quartz-image.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_QUARTZ_IMAGE_H
|
||||
#define CAIRO_QUARTZ_IMAGE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_QUARTZ_IMAGE_SURFACE
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_quartz_image_surface_create (cairo_surface_t *image_surface);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_quartz_image_surface_get_image (cairo_surface_t *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */
|
||||
# error Cairo was not compiled with support for the quartz-image backend
|
||||
#endif /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */
|
||||
|
||||
#endif /* CAIRO_QUARTZ_IMAGE_H */
|
||||
104
uppdev/plugin/cairo/lib/cairo-quartz-private.h
Normal file
104
uppdev/plugin/cairo/lib/cairo-quartz-private.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Calum Robinson
|
||||
* Copyright (C) 2006,2007 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Calum Robinson
|
||||
*
|
||||
* Contributor(s):
|
||||
* Calum Robinson <calumr@mac.com>
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_QUARTZ_PRIVATE_H
|
||||
#define CAIRO_QUARTZ_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#if CAIRO_HAS_QUARTZ_SURFACE
|
||||
#include "cairo-quartz.h"
|
||||
|
||||
typedef struct cairo_quartz_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
CGContextRef cgContext;
|
||||
CGAffineTransform cgContextBaseCTM;
|
||||
|
||||
void *imageData;
|
||||
cairo_surface_t *imageSurfaceEquiv;
|
||||
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
/* These are stored while drawing operations are in place, set up
|
||||
* by quartz_setup_source() and quartz_finish_source()
|
||||
*/
|
||||
CGAffineTransform sourceTransform;
|
||||
|
||||
CGImageRef sourceImage;
|
||||
cairo_surface_t *sourceImageSurface;
|
||||
CGRect sourceImageRect;
|
||||
|
||||
CGShadingRef sourceShading;
|
||||
CGPatternRef sourcePattern;
|
||||
|
||||
CGInterpolationQuality oldInterpolationQuality;
|
||||
} cairo_quartz_surface_t;
|
||||
|
||||
typedef struct cairo_quartz_image_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
CGImageRef image;
|
||||
cairo_image_surface_t *imageSurface;
|
||||
} cairo_quartz_image_surface_t;
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_quartz_verify_surface_size(int width, int height);
|
||||
|
||||
CGImageRef
|
||||
_cairo_quartz_create_cgimage (cairo_format_t format,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int stride,
|
||||
void *data,
|
||||
cairo_bool_t interpolate,
|
||||
CGColorSpaceRef colorSpaceOverride,
|
||||
CGDataProviderReleaseDataCallback releaseCallback,
|
||||
void *releaseInfo);
|
||||
|
||||
CGFontRef
|
||||
_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
|
||||
|
||||
#else
|
||||
|
||||
# error Cairo was not compiled with support for the quartz backend
|
||||
|
||||
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
|
||||
|
||||
#endif /* CAIRO_QUARTZ_PRIVATE_H */
|
||||
2752
uppdev/plugin/cairo/lib/cairo-quartz-surface.c
Normal file
2752
uppdev/plugin/cairo/lib/cairo-quartz-surface.c
Normal file
File diff suppressed because it is too large
Load diff
82
uppdev/plugin/cairo/lib/cairo-quartz.h
Normal file
82
uppdev/plugin/cairo/lib/cairo-quartz.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006, 2007 Mozilla Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_QUARTZ_H
|
||||
#define CAIRO_QUARTZ_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_QUARTZ_SURFACE
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_quartz_surface_create (cairo_format_t format,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
cairo_public CGContextRef
|
||||
cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
|
||||
|
||||
#if CAIRO_HAS_QUARTZ_FONT
|
||||
|
||||
/*
|
||||
* Quartz font support
|
||||
*/
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
|
||||
|
||||
#endif /* CAIRO_HAS_QUARTZ_FONT */
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else
|
||||
|
||||
# error Cairo was not compiled with support for the quartz backend
|
||||
|
||||
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
|
||||
|
||||
#endif /* CAIRO_QUARTZ_H */
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue