~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/layout/svg/renderer/src/libart/nsSVGLibartGlyphGeometryFT.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ----- BEGIN LICENSE BLOCK -----
 
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Mozilla Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/MPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is the Mozilla SVG project.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * .
 
19
 * Portions created by the Initial Developer are Copyright (C) 2002
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *    Leon Sha <leon.sha@sun.com>
 
24
 *    Alex Fritze <alex@croczilla.com>
 
25
 *
 
26
 * Alternatively, the contents of this file may be used under the terms of
 
27
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
28
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
29
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
30
 * of those above. If you wish to allow use of your version of this file only
 
31
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
32
 * use your version of this file under the terms of the NPL, indicate your
 
33
 * decision by deleting the provisions above and replace them with the notice
 
34
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
35
 * the provisions above, a recipient may use your version of this file under
 
36
 * the terms of any one of the MPL, the GPL or the LGPL.
 
37
 *
 
38
 * ----- END LICENSE BLOCK ----- */
 
39
 
 
40
 
 
41
#include "nsCOMPtr.h"
 
42
#include "nsISVGRendererGlyphGeometry.h"
 
43
#include "nsIDOMSVGMatrix.h"
 
44
#include "nsISVGGlyphGeometrySource.h"
 
45
#include "nsPromiseFlatString.h"
 
46
#include "nsIPresContext.h"
 
47
#include "nsMemory.h"
 
48
 
 
49
#include "nsSVGLibartFreetype.h"
 
50
#include "nsIServiceManager.h"
 
51
#include "nsISVGLibartGlyphMetricsFT.h"
 
52
#include "libart-incs.h"
 
53
#include "nsISVGLibartCanvas.h"
 
54
 
 
55
#include "nsIPresContext.h"
 
56
#include "nsIDeviceContext.h"
 
57
#include "nsIComponentManager.h"
 
58
 
 
59
/**
 
60
 * \addtogroup libart_renderer Libart Rendering Engine
 
61
 * @{
 
62
 */
 
63
////////////////////////////////////////////////////////////////////////
 
64
/**
 
65
 * Libart freetype-based glyph geometry implementation
 
66
 */
 
67
class nsSVGLibartGlyphGeometryFT : public nsISVGRendererGlyphGeometry
 
68
{
 
69
protected:
 
70
  friend nsresult NS_NewSVGLibartGlyphGeometryFT(nsISVGRendererGlyphGeometry **result,
 
71
                                                 nsISVGGlyphGeometrySource *src);
 
72
 
 
73
  nsSVGLibartGlyphGeometryFT();
 
74
  ~nsSVGLibartGlyphGeometryFT();
 
75
  nsresult Init(nsISVGGlyphGeometrySource* src);
 
76
 
 
77
public:
 
78
  // nsISupports interface:
 
79
  NS_DECL_ISUPPORTS
 
80
 
 
81
  // nsISVGRendererGlyphGeometry interface:
 
82
  NS_DECL_NSISVGRENDERERGLYPHGEOMETRY
 
83
 
 
84
protected:
 
85
  void PaintFill(nsISVGLibartCanvas* canvas, nsISVGLibartGlyphMetricsFT* metrics);
 
86
  nsCOMPtr<nsISVGGlyphGeometrySource> mSource;
 
87
 
 
88
 
 
89
  
 
90
};
 
91
 
 
92
/** @} */
 
93
 
 
94
//----------------------------------------------------------------------
 
95
// implementation:
 
96
 
 
97
nsSVGLibartGlyphGeometryFT::nsSVGLibartGlyphGeometryFT()
 
98
{
 
99
}
 
100
 
 
101
nsSVGLibartGlyphGeometryFT::~nsSVGLibartGlyphGeometryFT()
 
102
{
 
103
}
 
104
 
 
105
nsresult
 
106
nsSVGLibartGlyphGeometryFT::Init(nsISVGGlyphGeometrySource* src)
 
107
{
 
108
  mSource = src;
 
109
  return NS_OK;
 
110
}
 
111
 
 
112
nsresult
 
113
NS_NewSVGLibartGlyphGeometryFT(nsISVGRendererGlyphGeometry **result,
 
114
                               nsISVGGlyphGeometrySource *src)
 
115
{
 
116
  *result = nsnull;
 
117
  
 
118
  nsSVGLibartGlyphGeometryFT* gg = new nsSVGLibartGlyphGeometryFT();
 
119
  if (!gg) return NS_ERROR_OUT_OF_MEMORY;
 
120
 
 
121
  NS_ADDREF(gg);
 
122
 
 
123
  nsresult rv = gg->Init(src);
 
124
 
 
125
  if (NS_FAILED(rv)) {
 
126
    NS_RELEASE(gg);
 
127
    return rv;
 
128
  }
 
129
  
 
130
  *result = gg;
 
131
  return rv;
 
132
}
 
133
 
 
134
//----------------------------------------------------------------------
 
135
// nsISupports methods:
 
136
 
 
137
NS_IMPL_ADDREF(nsSVGLibartGlyphGeometryFT)
 
138
NS_IMPL_RELEASE(nsSVGLibartGlyphGeometryFT)
 
139
 
 
140
NS_INTERFACE_MAP_BEGIN(nsSVGLibartGlyphGeometryFT)
 
141
  NS_INTERFACE_MAP_ENTRY(nsISVGRendererGlyphGeometry)
 
142
  NS_INTERFACE_MAP_ENTRY(nsISupports)
 
143
NS_INTERFACE_MAP_END
 
144
 
 
145
 
 
146
//----------------------------------------------------------------------
 
147
// nsISVGRendererGlyphGeometry methods:
 
148
 
 
149
/** Implements void render(in nsISVGRendererCanvas canvas); */
 
150
NS_IMETHODIMP
 
151
nsSVGLibartGlyphGeometryFT::Render(nsISVGRendererCanvas *canvas)
 
152
{
 
153
  nsCOMPtr<nsISVGLibartCanvas> libartCanvas = do_QueryInterface(canvas);
 
154
  NS_ASSERTION(libartCanvas, "wrong svg render context for geometry!");
 
155
  if (!libartCanvas) return NS_ERROR_FAILURE;
 
156
  
 
157
  nsCOMPtr<nsISVGLibartGlyphMetricsFT> metrics;
 
158
  {
 
159
    nsCOMPtr<nsISVGRendererGlyphMetrics> xpmetrics;
 
160
    mSource->GetMetrics(getter_AddRefs(xpmetrics));
 
161
    metrics = do_QueryInterface(xpmetrics);
 
162
    NS_ASSERTION(metrics, "wrong metrics object!");
 
163
    if (!metrics) return NS_ERROR_FAILURE;
 
164
  }
 
165
 
 
166
  PRBool hasFill = PR_FALSE;
 
167
  {
 
168
    PRUint16 filltype;
 
169
    mSource->GetFillPaintType(&filltype);
 
170
    if (filltype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR)
 
171
      hasFill = PR_TRUE;
 
172
  }
 
173
 
 
174
  PRBool hasStroke = PR_FALSE;
 
175
  {
 
176
    PRUint16 stroketype;
 
177
    mSource->GetStrokePaintType(&stroketype);
 
178
    if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR)
 
179
      hasStroke = PR_TRUE;
 
180
  }
 
181
 
 
182
  if (hasFill)
 
183
    PaintFill(libartCanvas, metrics);
 
184
 
 
185
//  XXX
 
186
//  if (hasStroke)
 
187
//    PaintStroke(libartCanvas, metrics);
 
188
  
 
189
  return NS_OK;
 
190
}
 
191
 
 
192
 
 
193
/** Implements nsISVGRendererRegion update(in unsigned long updatemask); */
 
194
NS_IMETHODIMP
 
195
nsSVGLibartGlyphGeometryFT::Update(PRUint32 updatemask, nsISVGRendererRegion **_retval)
 
196
{
 
197
  *_retval = nsnull;      
 
198
  return NS_OK;
 
199
}
 
200
 
 
201
/** Implements nsISVGRendererRegion getCoveredRegion(); */
 
202
NS_IMETHODIMP
 
203
nsSVGLibartGlyphGeometryFT::GetCoveredRegion(nsISVGRendererRegion **_retval)
 
204
{
 
205
  *_retval = nsnull;
 
206
  return NS_OK;
 
207
}
 
208
 
 
209
/** Implements boolean containsPoint(in float x, in float y); */
 
210
NS_IMETHODIMP
 
211
nsSVGLibartGlyphGeometryFT::ContainsPoint(float x, float y, PRBool *_retval)
 
212
{
 
213
  *_retval = PR_FALSE;
 
214
  return NS_OK;
 
215
}
 
216
 
 
217
void
 
218
nsSVGLibartGlyphGeometryFT::PaintFill(nsISVGLibartCanvas* canvas,
 
219
                                      nsISVGLibartGlyphMetricsFT* metrics)
 
220
{
 
221
  FT_Matrix xform;
 
222
  FT_Vector delta;
 
223
  {
 
224
    float x,y;
 
225
    mSource->GetX(&x);
 
226
    mSource->GetY(&y);
 
227
    
 
228
    nsCOMPtr<nsIDOMSVGMatrix> ctm;
 
229
    mSource->GetCTM(getter_AddRefs(ctm));
 
230
    NS_ASSERTION(ctm, "graphic source didn't specify a ctm");
 
231
 
 
232
    // negations of B,C,F are to transform matrix from y-down to y-up
 
233
 
 
234
    float a,b,c,d,e,f;
 
235
    ctm->GetA(&a);
 
236
    xform.xx = (FT_Fixed)(a*0x10000L); // convert to 16.16 fixed
 
237
    ctm->GetB(&b);
 
238
    xform.yx = (FT_Fixed)(-b*0x10000L);
 
239
    ctm->GetC(&c);
 
240
    xform.xy = (FT_Fixed)(-c*0x10000L);
 
241
    ctm->GetD(&d);
 
242
    xform.yy = (FT_Fixed)(d*0x10000L);
 
243
    ctm->GetE(&e);
 
244
    delta.x = (FT_Pos)((a*x+c*y+e)*64); // convert to 26.6 fixed
 
245
    ctm->GetF(&f);
 
246
    delta.y = (FT_Pos)(-(b*x+d*y+f)*64);
 
247
  }
 
248
  
 
249
  float opacity;
 
250
  mSource->GetFillOpacity(&opacity);
 
251
 
 
252
  ArtColor fill_color;
 
253
  {
 
254
    nscolor rgb;
 
255
    mSource->GetFillPaint(&rgb);
 
256
    canvas->GetArtColor(rgb, fill_color);
 
257
  }
 
258
  
 
259
  PRUint32 glyph_count = metrics->GetGlyphCount();
 
260
  
 
261
  for (PRUint32 i=0; i<glyph_count; ++i) {
 
262
    FT_Glyph glyph;
 
263
    nsSVGLibartFreetype::ft2->GlyphCopy(metrics->GetGlyphAt(i), &glyph);
 
264
 
 
265
    nsSVGLibartFreetype::ft2->GlyphTransform(glyph, &xform, &delta);
 
266
    
 
267
    if (NS_SUCCEEDED(nsSVGLibartFreetype::ft2->GlyphToBitmap(&glyph,
 
268
                                                             FT_RENDER_MODE_NORMAL,
 
269
                                                             nsnull, // translation
 
270
                                                             1 // destroy glyph copy
 
271
                                                             ))) {
 
272
      FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
 
273
      
 
274
      ArtRender* render = canvas->NewRender(bitmap->left,
 
275
                                            -bitmap->top,
 
276
                                            bitmap->left+bitmap->bitmap.width,
 
277
                                            -bitmap->top+bitmap->bitmap.rows);
 
278
      if (render) {
 
279
        art_render_image_solid(render, fill_color);
 
280
        art_render_mask_solid(render, (int)(0x10000*opacity));
 
281
        
 
282
        art_render_mask(render,
 
283
                        bitmap->left,
 
284
                        -bitmap->top,
 
285
                        bitmap->left+bitmap->bitmap.width,
 
286
                        -bitmap->top+bitmap->bitmap.rows,
 
287
                        bitmap->bitmap.buffer,
 
288
                        bitmap->bitmap.pitch);
 
289
        canvas->InvokeRender(render);
 
290
      }
 
291
    }
 
292
    nsSVGLibartFreetype::ft2->DoneGlyph(glyph);
 
293
  }
 
294
}