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

« back to all changes in this revision

Viewing changes to mozilla/gfx/src/beos/nsFontMetricsBeOS.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
/* vim:set cindent ts=2 sts=2 sw=2 et: */
 
3
/* ***** BEGIN LICENSE BLOCK *****
 
4
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
5
 *
 
6
 * The contents of this file are subject to the Netscape Public License
 
7
 * Version 1.1 (the "License"); you may not use this file except in
 
8
 * compliance with the License. You may obtain a copy of the License at
 
9
 * http://www.mozilla.org/NPL/
 
10
 *
 
11
 * Software distributed under the License is distributed on an "AS IS" basis,
 
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
13
 * for the specific language governing rights and limitations under the
 
14
 * License.
 
15
 *
 
16
 * The Original Code is mozilla.org code.
 
17
 *
 
18
 * The Initial Developer of the Original Code is 
 
19
 * Netscape Communications Corporation.
 
20
 * Portions created by the Initial Developer are Copyright (C) 1998
 
21
 * the Initial Developer. All Rights Reserved.
 
22
 *
 
23
 * Contributor(s):
 
24
 *   Yannick Koehler <koehler@mythrium.com>
 
25
 *   Christian M Hoffman <chrmhoffmann@web.de>
 
26
 *   Makoto hamanaka <VYA04230@nifty.com>
 
27
 *   Paul Ashford <arougthopher@lizardland.net>
 
28
 *
 
29
 *
 
30
 * Alternatively, the contents of this file may be used under the terms of
 
31
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
32
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
33
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
34
 * of those above. If you wish to allow use of your version of this file only
 
35
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
36
 * use your version of this file under the terms of the NPL, indicate your
 
37
 * decision by deleting the provisions above and replace them with the notice
 
38
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
39
 * the provisions above, a recipient may use your version of this file under
 
40
 * the terms of any one of the NPL, the GPL or the LGPL.
 
41
 *
 
42
 * ***** END LICENSE BLOCK ***** */
 
43
 
 
44
#include "nsQuickSort.h" 
 
45
#include "nsFontMetricsBeOS.h" 
 
46
#include "nsIServiceManager.h" 
 
47
#include "nsICharsetConverterManager.h" 
 
48
#include "nsISaveAsCharset.h" 
 
49
#include "nsIPrefService.h" 
 
50
#include "nsIPrefBranch.h"
 
51
#include "nsCOMPtr.h" 
 
52
#include "nspr.h" 
 
53
#include "nsHashtable.h" 
 
54
#include "nsReadableUtils.h"
 
55
 
 
56
#include <UnicodeBlockObjects.h>
 
57
 
 
58
#undef USER_DEFINED 
 
59
#define USER_DEFINED "x-user-def" 
 
60
 
 
61
#undef NOISY_FONTS
 
62
#undef REALLY_NOISY_FONTS
 
63
 
 
64
nsFontMetricsBeOS::nsFontMetricsBeOS()
 
65
  :mEmulateBold(PR_FALSE)
 
66
{
 
67
}
 
68
 
 
69
nsFontMetricsBeOS::~nsFontMetricsBeOS()
 
70
{
 
71
  if (nsnull != mFont) 
 
72
  {
 
73
    delete mFont;
 
74
    mFont = nsnull;
 
75
  }
 
76
  if (mDeviceContext) 
 
77
  {
 
78
    // Notify our device context that owns us so that it can update its font cache
 
79
    mDeviceContext->FontMetricsDeleted(this);
 
80
    mDeviceContext = nsnull;
 
81
  }
 
82
}
 
83
 
 
84
NS_IMPL_ISUPPORTS1(nsFontMetricsBeOS, nsIFontMetrics) 
 
85
 
 
86
// a structure to hold a font family list
 
87
typedef struct nsFontEnumParamsBeOS {
 
88
  nsFontMetricsBeOS *metrics;
 
89
  nsStringArray family;
 
90
  nsVoidArray isgeneric;
 
91
} NS_FONT_ENUM_PARAMS_BEOS;
 
92
 
 
93
// a callback func to get a font family list from a nsFont object
 
94
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
 
95
{
 
96
  NS_FONT_ENUM_PARAMS_BEOS *param = (NS_FONT_ENUM_PARAMS_BEOS *) aData;
 
97
  param->family.AppendString(aFamily);
 
98
  param->isgeneric.AppendElement((void*) aGeneric);
 
99
  if (aGeneric)
 
100
    return PR_FALSE;
 
101
 
 
102
  return PR_TRUE;
 
103
}
 
104
 
 
105
NS_IMETHODIMP nsFontMetricsBeOS::Init(const nsFont& aFont, nsIAtom* aLangGroup,
 
106
  nsIDeviceContext* aContext)
 
107
{
 
108
  NS_ASSERTION(!(nsnull == aContext), "attempt to init fontmetrics with null device context");
 
109
 
 
110
  mLangGroup = aLangGroup;
 
111
  mDeviceContext = aContext;
 
112
 
 
113
  // get font family list
 
114
  NS_FONT_ENUM_PARAMS_BEOS param;
 
115
  param.metrics = this;
 
116
  aFont.EnumerateFamilies(FontEnumCallback, &param);
 
117
 
 
118
  PRInt16  face = 0;
 
119
 
 
120
  mFont = new nsFont(aFont);
 
121
  if (!mFont)
 
122
    return NS_ERROR_OUT_OF_MEMORY;
 
123
 
 
124
  float       app2dev, app2twip;
 
125
  app2dev = aContext->AppUnitsToDevUnits();
 
126
  app2twip = aContext->DevUnitsToTwips();
 
127
 
 
128
  app2twip *= app2dev;
 
129
  float rounded = ((float)NSIntPointsToTwips(NSTwipsToFloorIntPoints(nscoord(mFont->size * app2twip)))) / app2twip;
 
130
 
 
131
  // process specified fonts from first item of the array.
 
132
  // stop processing next when a real font found;
 
133
  PRBool fontfound = PR_FALSE;
 
134
  PRBool isfixed = PR_FALSE;
 
135
  for (int i=0 ; i<param.family.Count() && !fontfound ; i++) 
 
136
  {
 
137
    nsString *fam = param.family.StringAt(i);
 
138
    PRBool isgeneric = ( param.isgeneric[i] ) ? PR_TRUE: PR_FALSE;
 
139
    NS_ConvertUTF16toUTF8 family(*fam);
 
140
    // Fallback
 
141
    isfixed = family.Equals("monospace") || family.Equals("fixed");
 
142
    if (!isgeneric) 
 
143
    {
 
144
      // non-generic font
 
145
      if (count_font_styles((font_family)family.get()) <= 0) 
 
146
      {
 
147
        // the specified font does not exist on this computer.
 
148
        continue;
 
149
      }
 
150
      mFontHandle.SetFamilyAndStyle( (font_family)family.get(), NULL );
 
151
      fontfound = PR_TRUE;
 
152
      break;
 
153
    } 
 
154
    else 
 
155
    {
 
156
      // family is generic string like 
 
157
      // "serif" "sans-serif" "cursive" "fantasy" "monospace" "-moz-fixed"
 
158
      // so look up preferences and get real family name
 
159
      const char *lang;
 
160
      aLangGroup->GetUTF8String( &lang );
 
161
      char prop[256];
 
162
      snprintf( prop, sizeof(prop), "%s.%s", family.get(), lang );
 
163
 
 
164
      // look up prefs
 
165
      nsXPIDLCString real_family;
 
166
      nsresult res;
 
167
      //NS_WITH_SERVICE( nsIPref, prefs, kPrefCID, &res );
 
168
      nsCOMPtr<nsIPrefService> prefs = do_GetService( NS_PREFSERVICE_CONTRACTID, &res );
 
169
      if (NS_SUCCEEDED(res)) 
 
170
      {
 
171
        nsCOMPtr<nsIPrefBranch> branch;
 
172
        prefs->GetBranch("font.name.", getter_AddRefs(branch));
 
173
        branch->GetCharPref(prop, getter_Copies(real_family));
 
174
 
 
175
        if (!real_family.IsEmpty() && real_family.Length() <= B_FONT_FAMILY_LENGTH  && count_font_styles((font_family)real_family.get()) > 0) 
 
176
        {
 
177
          mFontHandle.SetFamilyAndStyle( (font_family)real_family.get(), NULL );
 
178
          fontfound = PR_TRUE;
 
179
          break;        
 
180
        }
 
181
      } 
 
182
      // not successful. use system font.
 
183
      if (isfixed)
 
184
        mFontHandle = be_fixed_font;
 
185
      else
 
186
        mFontHandle = be_plain_font;
 
187
      fontfound = PR_TRUE;
 
188
      break;
 
189
    }
 
190
  }
 
191
 
 
192
  // if got no font, then use system font.
 
193
  if (!fontfound)
 
194
  {
 
195
    if (isfixed)
 
196
      mFontHandle = be_fixed_font;
 
197
    else
 
198
      mFontHandle = be_plain_font;
 
199
  } 
 
200
 
 
201
  if (aFont.style == NS_FONT_STYLE_ITALIC)
 
202
    face |= B_ITALIC_FACE;
 
203
 
 
204
  if ( aFont.weight > NS_FONT_WEIGHT_NORMAL )
 
205
        face |= B_BOLD_FACE;
 
206
        
 
207
  // I don't think B_UNDERSCORE_FACE and B_STRIKEOUT_FACE really works...
 
208
  // instead, nsTextFrame do them for us. ( my guess... Makoto Hamanaka )
 
209
  if ( aFont.decorations & NS_FONT_DECORATION_UNDERLINE )
 
210
        face |= B_UNDERSCORE_FACE;
 
211
        
 
212
  if ( aFont.decorations & NS_FONT_DECORATION_LINE_THROUGH )
 
213
        face |= B_STRIKEOUT_FACE;
 
214
        
 
215
  mFontHandle.SetFace( face );
 
216
  // emulate italic and bold if the selected family has no such style
 
217
  if (aFont.style == NS_FONT_STYLE_ITALIC
 
218
    && !(mFontHandle.Face() & B_ITALIC_FACE)) 
 
219
    mFontHandle.SetShear(105.0);
 
220
  if ( aFont.weight > NS_FONT_WEIGHT_NORMAL
 
221
    && !(mFontHandle.Face() & B_BOLD_FACE)) 
 
222
    mEmulateBold = PR_TRUE;
 
223
 
 
224
  mFontHandle.SetSize( rounded * app2dev );
 
225
  fflush(stdout);
 
226
#ifdef NOISY_FONTS
 
227
#ifdef DEBUG
 
228
  fprintf(stderr, "looking for font %s (%d)", wildstring, aFont.size / app2twip);
 
229
#endif
 
230
#endif
 
231
 
 
232
  RealizeFont(aContext);
 
233
 
 
234
  return NS_OK;
 
235
}
 
236
 
 
237
NS_IMETHODIMP  nsFontMetricsBeOS::Destroy()
 
238
{
 
239
  mDeviceContext = nsnull;
 
240
  return NS_OK;
 
241
}
 
242
 
 
243
 
 
244
void nsFontMetricsBeOS::RealizeFont(nsIDeviceContext* aContext)
 
245
{
 
246
  float f;
 
247
  f = aContext->DevUnitsToAppUnits();
 
248
  
 
249
  struct font_height height;
 
250
  mFontHandle.GetHeight( &height );
 
251
 
 
252
  struct font_height emHeight; 
 
253
  mFontHandle.GetHeight(&emHeight);
 
254
  //be_plain_font->GetHeight(&emHeight); 
 
255
 
 
256
  int lineSpacing = nscoord(height.ascent + height.descent); 
 
257
  if (lineSpacing > (emHeight.ascent + emHeight.descent))
 
258
    mLeading = nscoord((lineSpacing - (emHeight.ascent + emHeight.descent)) * f); 
 
259
  else
 
260
    mLeading = 0; 
 
261
 
 
262
  mEmHeight = PR_MAX(1, nscoord((emHeight.ascent + emHeight.descent) * f)); 
 
263
  mEmAscent = nscoord(height.ascent * (emHeight.ascent + emHeight.descent) * f / lineSpacing); 
 
264
  mEmDescent = mEmHeight - mEmAscent; 
 
265
 
 
266
  mMaxHeight = nscoord((height.ascent + 
 
267
                        height.descent) * f) ; 
 
268
  mMaxAscent = nscoord(height.ascent * f) ;
 
269
  mMaxDescent = nscoord(height.descent * f);
 
270
  
 
271
  mMaxAdvance = nscoord((mFontHandle.BoundingBox().Width()+1) * f); //fyy +1
 
272
 
 
273
  float rawWidth = mFontHandle.StringWidth("x"); 
 
274
  mAveCharWidth = NSToCoordRound(rawWidth * f); 
 
275
 
 
276
  // 56% of ascent, best guess for non-true type 
 
277
  mXHeight = NSToCoordRound((float) height.ascent* f * 0.56f); 
 
278
 
 
279
  rawWidth = mFontHandle.StringWidth(" "); 
 
280
  mSpaceWidth = NSToCoordRound(rawWidth * f); 
 
281
 
 
282
/* Temp */ 
 
283
  mUnderlineOffset = -NSToIntRound(MAX (1, floor (0.1 * (height.ascent + height.descent + height.leading) + 0.5)) * f); 
 
284
  
 
285
  mUnderlineSize = NSToIntRound(MAX(1, floor (0.05 * (height.ascent + height.descent + height.leading) + 0.5)) * f); 
 
286
 
 
287
  mSuperscriptOffset = mXHeight; 
 
288
 
 
289
  mSubscriptOffset = mXHeight; 
 
290
 
 
291
  /* need better way to calculate this */ 
 
292
  mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); 
 
293
  mStrikeoutSize = mUnderlineSize; 
 
294
 
 
295
}
 
296
 
 
297
NS_IMETHODIMP  nsFontMetricsBeOS::GetXHeight(nscoord& aResult)
 
298
{
 
299
  aResult = mXHeight;
 
300
  return NS_OK;
 
301
}
 
302
 
 
303
NS_IMETHODIMP  nsFontMetricsBeOS::GetSuperscriptOffset(nscoord& aResult)
 
304
{
 
305
  aResult = mSuperscriptOffset;
 
306
  return NS_OK;
 
307
}
 
308
 
 
309
NS_IMETHODIMP  nsFontMetricsBeOS::GetSubscriptOffset(nscoord& aResult)
 
310
{
 
311
  aResult = mSubscriptOffset;
 
312
  return NS_OK;
 
313
}
 
314
 
 
315
NS_IMETHODIMP  nsFontMetricsBeOS::GetStrikeout(nscoord& aOffset, nscoord& aSize)
 
316
{
 
317
  aOffset = mStrikeoutOffset; 
 
318
  aSize = mStrikeoutSize; 
 
319
//  aOffset = nscoord( ( mAscent / 2 ) - mDescent ); 
 
320
//  aSize = nscoord( 20 );  // FIXME Put 1 pixel which equal 20 twips.. 
 
321
  return NS_OK;
 
322
}
 
323
 
 
324
NS_IMETHODIMP  nsFontMetricsBeOS::GetUnderline(nscoord& aOffset, nscoord& aSize)
 
325
{
 
326
  aOffset = mUnderlineOffset;
 
327
  aSize = mUnderlineSize;
 
328
  //aOffset = nscoord( 0 ); // FIXME
 
329
  //aSize = nscoord( 20 );  // FIXME
 
330
  return NS_OK;
 
331
}
 
332
 
 
333
NS_IMETHODIMP  nsFontMetricsBeOS::GetHeight(nscoord &aHeight)
 
334
 
335
  aHeight = mMaxHeight; 
 
336
  return NS_OK; 
 
337
 
338
 
 
339
NS_IMETHODIMP  nsFontMetricsBeOS::GetNormalLineHeight(nscoord &aHeight) 
 
340
{
 
341
  aHeight = mEmHeight + mLeading; 
 
342
  return NS_OK;
 
343
}
 
344
 
 
345
NS_IMETHODIMP  nsFontMetricsBeOS::GetLeading(nscoord &aLeading)
 
346
{
 
347
  aLeading = mLeading;
 
348
  return NS_OK;
 
349
}
 
350
 
 
351
NS_IMETHODIMP  nsFontMetricsBeOS::GetEmHeight(nscoord &aHeight) 
 
352
 
353
  aHeight = mEmHeight; 
 
354
  return NS_OK; 
 
355
 
356
 
 
357
NS_IMETHODIMP  nsFontMetricsBeOS::GetEmAscent(nscoord &aAscent) 
 
358
 
359
  aAscent = mEmAscent; 
 
360
  return NS_OK; 
 
361
 
362
 
 
363
NS_IMETHODIMP  nsFontMetricsBeOS::GetEmDescent(nscoord &aDescent) 
 
364
 
365
  aDescent = mEmDescent; 
 
366
  return NS_OK; 
 
367
 
368
 
 
369
NS_IMETHODIMP  nsFontMetricsBeOS::GetMaxHeight(nscoord &aHeight) 
 
370
 
371
  aHeight = mMaxHeight; 
 
372
  return NS_OK; 
 
373
 
374
 
 
375
NS_IMETHODIMP  nsFontMetricsBeOS::GetMaxAscent(nscoord &aAscent)
 
376
{
 
377
  aAscent = mMaxAscent;
 
378
  return NS_OK;
 
379
}
 
380
 
 
381
NS_IMETHODIMP  nsFontMetricsBeOS::GetMaxDescent(nscoord &aDescent)
 
382
{
 
383
  aDescent = mMaxDescent;
 
384
  return NS_OK;
 
385
}
 
386
 
 
387
NS_IMETHODIMP  nsFontMetricsBeOS::GetMaxAdvance(nscoord &aAdvance)
 
388
{
 
389
  aAdvance = mMaxAdvance;
 
390
  return NS_OK;
 
391
}
 
392
 
 
393
NS_IMETHODIMP nsFontMetricsBeOS::GetAveCharWidth(nscoord &aAveCharWidth)
 
394
{
 
395
  aAveCharWidth = mAveCharWidth;
 
396
  return NS_OK;
 
397
}
 
398
 
 
399
NS_IMETHODIMP  nsFontMetricsBeOS::GetSpaceWidth(nscoord &aSpaceWidth) 
 
400
 
401
  aSpaceWidth = mSpaceWidth; 
 
402
  return NS_OK; 
 
403
 
404
 
 
405
NS_IMETHODIMP  nsFontMetricsBeOS::GetFont(const nsFont*& aFont)
 
406
{
 
407
  aFont = mFont;
 
408
  return NS_OK;
 
409
}
 
410
 
 
411
NS_IMETHODIMP  nsFontMetricsBeOS::GetLangGroup(nsIAtom** aLangGroup)
 
412
{
 
413
  if (!aLangGroup)
 
414
    return NS_ERROR_NULL_POINTER;
 
415
 
 
416
  *aLangGroup = mLangGroup;
 
417
  NS_IF_ADDREF(*aLangGroup);
 
418
 
 
419
  return NS_OK;
 
420
}
 
421
 
 
422
NS_IMETHODIMP  nsFontMetricsBeOS::GetFontHandle(nsFontHandle &aHandle)
 
423
{
 
424
  aHandle = (nsFontHandle)&mFontHandle;
 
425
  return NS_OK;
 
426
 
427
 
 
428
nsresult 
 
429
nsFontMetricsBeOS::FamilyExists(const nsString& aName) 
 
430
 
431
  //Do we really need it here? BeOS supports UTF-8 overall natively,
 
432
  //including UTF-8 fonts names with non-ascii chars inside
 
433
  if (!IsASCII(aName)) 
 
434
    return NS_ERROR_FAILURE; 
 
435
 
 
436
  nsCAutoString name; 
 
437
  name.AssignWithConversion(aName.get()); 
 
438
  ToLowerCase(name); 
 
439
  PRBool  isthere = PR_FALSE; 
 
440
 
 
441
  int32 numFamilies = count_font_families(); 
 
442
  for (int32 i = 0; i < numFamilies; i++) 
 
443
  { 
 
444
    font_family family; 
 
445
    uint32 flags; 
 
446
    if (get_font_family(i, &family, &flags) == B_OK) 
 
447
    { 
 
448
      if (name.Equals(family) == 0) 
 
449
      {
 
450
        isthere = PR_TRUE; 
 
451
        break; 
 
452
      } 
 
453
    } 
 
454
  } 
 
455
 
 
456
  //printf("%s there? %s\n", name.get(), isthere?"Yes":"No" ); 
 
457
 
 
458
  if (PR_TRUE == isthere) 
 
459
    return NS_OK; 
 
460
  else 
 
461
    return NS_ERROR_FAILURE; 
 
462
 
463
 
 
464
// The Font Enumerator 
 
465
 
 
466
nsFontEnumeratorBeOS::nsFontEnumeratorBeOS() 
 
467
 
468
 
469
 
 
470
NS_IMPL_ISUPPORTS1(nsFontEnumeratorBeOS, nsIFontEnumerator)
 
471
 
 
472
static int 
 
473
CompareFontNames(const void* aArg1, const void* aArg2, void* aClosure) 
 
474
 
475
  const PRUnichar* str1 = *((const PRUnichar**) aArg1); 
 
476
  const PRUnichar* str2 = *((const PRUnichar**) aArg2); 
 
477
 
 
478
  // XXX add nsICollation stuff 
 
479
 
 
480
  return nsCRT::strcmp(str1, str2); 
 
481
 
482
 
 
483
static int
 
484
FontMatchesGenericType(font_family family, uint32 flags, const char* aGeneric,
 
485
  const char* aLangGroup)
 
486
{
 
487
  //Call from EnumerateAllFonts. Matches all.
 
488
  //Return 1 immediately, because nsnull as argument of strstr causes crashes
 
489
  if(aGeneric == nsnull || aLangGroup == nsnull)
 
490
    return 1;
 
491
  if (!strcmp(aLangGroup, "ja"))    
 
492
    return 1;
 
493
  if (strstr(aLangGroup, "zh"))
 
494
    return 1;
 
495
  if (!strcmp(aLangGroup, "ko"))
 
496
    return 1;
 
497
  if (!strcmp(aLangGroup, "th"))
 
498
    return 1;
 
499
  if (!strcmp(aLangGroup, "he"))
 
500
    return 1;
 
501
  if (!strcmp(aLangGroup, "ar"))
 
502
    return 1;
 
503
  if (strstr(aLangGroup, "user-def"))
 
504
    return 1;
 
505
  if (!strcmp(aLangGroup, "unicode"))
 
506
    return 1;
 
507
 
 
508
  if (strstr(aGeneric, "fantasy") 
 
509
  // Let's use all possible fonts as decorative
 
510
#if 0
 
511
    && (strstr(family, "Baskerville") || 
 
512
        strstr(family, "Chicago") ||
 
513
        strstr(family, "Copprpl") ||
 
514
        strstr(family, "Embassy") ||
 
515
        strstr(family, "Europe") ||
 
516
        strstr(family, "Garmnd") ||
 
517
        strstr(family, "Impact") ||
 
518
        strstr(family, "ProFont") ||
 
519
        strstr(family, "VAGRounded"))
 
520
#endif      
 
521
    )
 
522
    return 1;
 
523
  // Hack. Sniffing is based on wide-spread names for serif and sansserif.   No function in BeOS to get full font-info.
 
524
  // NB! "Haru Tohaba" and "Haru" need EXACT match - !strcmp seems suspicious in that case, timeless !!!
 
525
  if (!strcmp(aGeneric, "serif") && 
 
526
     (strstr(family, "Dutch") || strstr(family, "Times") || strstr(family, "Roman") ||
 
527
      strstr(family, "CentSchbook") || strstr(family, "Georgia") || strstr(family, "Baskerville") ||
 
528
      strstr(family, "Garmnd") || strstr(family, "Cyberbit") || strcmp(family, "Haru Tohaba") == 0))
 
529
    return 1;
 
530
  if (!strcmp(aGeneric, "sans-serif") && 
 
531
     (strstr(family, "Arial") || strstr(family, "Chianti") || strstr(family, "Helv") ||
 
532
      strstr(family, "Humnst") || strstr(family, "Swiss") || strstr(family, "Tahoma") ||
 
533
      strstr(family, "Sans") || strstr(family, "sans") || strstr(family, "Verdana") || 
 
534
      strstr(family, "Zurich") || strcmp(family, "Haru") == 0))
 
535
    return 1;
 
536
  if ((strstr(aGeneric, "monospace") || strstr(aGeneric, "-moz-fixed")) && 
 
537
    (flags & B_IS_FIXED || strstr(family, "Cour") || strstr(family, "Consol") ||
 
538
     strstr(family, "Fixed") || strstr(family, "Kurier") || strstr(family, "Lucida") ||
 
539
     strstr(family, "Mono") || strstr(family, "console") || strstr(family, "mono") ||
 
540
     strstr(family, "fixed")))
 
541
    return 1;
 
542
  if (strstr(aGeneric, "cursive") && 
 
543
    (strstr(family, "Cursiv") || strstr(family, "Kursiv") || strstr(family, "Script") ||
 
544
     strstr(family, "kursiv") || strstr(family, "Embassy") || strstr(family, "script") || 
 
545
     strstr(family, "Brush")))
 
546
    return 1;
 
547
 
 
548
  return 0;
 
549
}
 
550
 
 
551
static int MatchesLangGroup(font_family family,  const char* aLangGroup) 
 
552
{
 
553
  BFont font;
 
554
  font.SetFamilyAndStyle(family, NULL);
 
555
  unicode_block lang = font.Blocks();
 
556
  int match = 0;
 
557
 
 
558
  //No restrictions
 
559
  if ((strstr(aLangGroup, "user-def") || strstr(aLangGroup, "unicode")))
 
560
    return 1; 
 
561
  // "tr" and "central-euro" need more testing, but seems OK
 
562
  if ((strstr(aLangGroup, "baltic") || strstr(aLangGroup, "central-euro") || strstr(aLangGroup, "western")) && 
 
563
    lang.Includes(B_LATIN1_SUPPLEMENT_BLOCK))
 
564
    return 1;
 
565
  if (strstr(aLangGroup, "tr") && lang.Includes(B_LATIN_EXTENDED_A_BLOCK))
 
566
    return 1;
 
567
  if (strstr(aLangGroup, "el") && lang.Includes(B_BASIC_GREEK_BLOCK))
 
568
    return 1;
 
569
  if (strstr(aLangGroup, "cyrillic") && lang.Includes(B_CYRILLIC_BLOCK))
 
570
    return 1;
 
571
  if (strstr(aLangGroup, "he") && lang.Includes(B_BASIC_HEBREW_BLOCK))
 
572
    return 1;
 
573
  if (strstr(aLangGroup, "ar") && lang.Includes(B_BASIC_ARABIC_BLOCK))
 
574
    return 1;
 
575
  if (strstr(aLangGroup, "th") && lang.Includes(B_THAI_BLOCK))
 
576
    return 1;
 
577
  // CKJ settings need more verification
 
578
  if ((strstr(aLangGroup, "ja") || strstr(aLangGroup, "ko") || strstr(aLangGroup, "zh") ) &&
 
579
    (lang.Includes(B_CJK_UNIFIED_IDEOGRAPHS_BLOCK) ||
 
580
     lang.Includes(B_CJK_MISCELLANEOUS_BLOCK) ||
 
581
     lang.Includes(B_ENCLOSED_CJK_LETTERS_AND_MONTHS_BLOCK) ||
 
582
     lang.Includes(B_CJK_COMPATIBILITY_BLOCK) ||
 
583
     lang.Includes(B_CJK_COMPATIBILITY_IDEOGRAPHS_BLOCK) ||
 
584
     lang.Includes(B_CJK_COMPATIBILITY_FORMS_BLOCK))) 
 
585
    match = 1;  
 
586
  // additional check for partial CKJ blocks
 
587
  if (strstr(aLangGroup, "ja") && (lang.Includes(B_HIRAGANA_BLOCK) || lang.Includes(B_KATAKANA_BLOCK) ))
 
588
    match = 1; 
 
589
  if (strstr(aLangGroup, "ko") && (lang.Includes(B_HANGUL_BLOCK)))
 
590
    match = 1;   
 
591
  if (strstr(aLangGroup, "zh") && (lang.Includes(B_HIGH_SURROGATES_BLOCK) || lang.Includes(B_LOW_SURROGATES_BLOCK) ))
 
592
    match = 1; 
 
593
   
 
594
 
 
595
 return match; 
 
596
}
 
597
 
 
598
static nsresult EnumFonts(const char * aLangGroup, const char* aGeneric, PRUint32* aCount, PRUnichar*** aResult) 
 
599
 
600
  nsString font_name; 
 
601
    
 
602
  int32 numFamilies = count_font_families(); 
 
603
 
 
604
  PRUnichar** array = 
 
605
    (PRUnichar**) nsMemory::Alloc(numFamilies * sizeof(PRUnichar*)); 
 
606
  if (!array) 
 
607
    return NS_ERROR_OUT_OF_MEMORY; 
 
608
  int j = 0;
 
609
  for(int32 i = 0; i < numFamilies; i++) 
 
610
  {
 
611
    font_family family; 
 
612
    uint32 flags; 
 
613
    if (get_font_family(i, &family, &flags) == B_OK) 
 
614
    {
 
615
      if (family && (!aLangGroup || MatchesLangGroup(family,  aLangGroup)))
 
616
      {
 
617
        if(FontMatchesGenericType(family, flags, aGeneric, aLangGroup))
 
618
        {
 
619
          font_name.AssignWithConversion(family); 
 
620
          if (!(array[j] = ToNewUnicode(font_name)))
 
621
            break; 
 
622
          ++j;
 
623
        }
 
624
      }
 
625
    }
 
626
  } 
 
627
 
 
628
  NS_QuickSort(array, j, sizeof(PRUnichar*), CompareFontNames, nsnull); 
 
629
 
 
630
  *aCount = j; 
 
631
  if (*aCount)
 
632
    *aResult = array; 
 
633
  else 
 
634
    nsMemory::Free(array); 
 
635
 
 
636
  return NS_OK; 
 
637
 
638
 
 
639
NS_IMETHODIMP 
 
640
nsFontEnumeratorBeOS::EnumerateAllFonts(PRUint32* aCount, PRUnichar*** aResult) 
 
641
 
642
  NS_ENSURE_ARG_POINTER(aResult); 
 
643
  *aResult = nsnull; 
 
644
  NS_ENSURE_ARG_POINTER(aCount); 
 
645
  *aCount = 0; 
 
646
 
 
647
  return EnumFonts(nsnull, nsnull, aCount, aResult); 
 
648
 
649
 
 
650
NS_IMETHODIMP 
 
651
nsFontEnumeratorBeOS::EnumerateFonts(const char* aLangGroup, 
 
652
  const char* aGeneric, PRUint32* aCount, PRUnichar*** aResult) 
 
653
 
654
  NS_ENSURE_ARG_POINTER(aResult); 
 
655
  *aResult = nsnull; 
 
656
  NS_ENSURE_ARG_POINTER(aCount); 
 
657
  *aCount = 0; 
 
658
 
 
659
  // aLangGroup=null or ""  means any (i.e., don't care)
 
660
  // aGeneric=null or ""  means any (i.e, don't care)
 
661
  const char* langGroup = nsnull;
 
662
  if (aLangGroup && *aLangGroup)
 
663
    langGroup = aLangGroup;
 
664
  const char* generic = nsnull;
 
665
  if (aGeneric && *aGeneric)
 
666
    generic = aGeneric;
 
667
 
 
668
  return EnumFonts(langGroup, generic, aCount, aResult); 
 
669
}
 
670
 
 
671
NS_IMETHODIMP
 
672
nsFontEnumeratorBeOS::HaveFontFor(const char* aLangGroup, PRBool* aResult)
 
673
{
 
674
  NS_ENSURE_ARG_POINTER(aLangGroup); 
 
675
  NS_ENSURE_ARG_POINTER(aResult); 
 
676
  *aResult = PR_TRUE; 
 
677
  // XXX stub
 
678
  return NS_OK;
 
679
}
 
680
 
 
681
NS_IMETHODIMP
 
682
nsFontEnumeratorBeOS::GetDefaultFont(const char *aLangGroup, 
 
683
  const char *aGeneric, PRUnichar **aResult)
 
684
{
 
685
  // aLangGroup=null or ""  means any (i.e., don't care)
 
686
  // aGeneric=null or ""  means any (i.e, don't care)
 
687
 
 
688
  NS_ENSURE_ARG_POINTER(aResult);
 
689
  *aResult = nsnull;
 
690
 
 
691
  return NS_OK;
 
692
}
 
693
 
 
694
NS_IMETHODIMP
 
695
nsFontEnumeratorBeOS::UpdateFontList(PRBool *updateFontList)
 
696
{
 
697
  *updateFontList = PR_FALSE; // always return false for now
 
698
  return NS_OK;
 
699
}
 
700