This commit was manufactured by cvs2svn to create branch

'DOM_AGNOSTIC3_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/DOM_AGNOSTIC3_BRANCH@199651 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
(no author)
2006-06-10 00:21:06 +00:00
parent f88edc1438
commit f8612fcb21
35 changed files with 6481 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul Sandoz (paul.sandoz@sun.com)
* Bill Haneman (bill.haneman@sun.com)
* John Gaunt (jgaunt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(91F0A56C-11BE-47C7-8D02-7C15E00C05F5)]
interface nsIAccessibleEditableText : nsISupports
{
/**
* Set font styles, such as italic, bold...
*/
void setAttributes (in long startPos, in long endPos,
in nsISupports attributes);
void setTextContents (in AString text);
void insertText (in AString text, in long position);
void copyText (in long startPos, in long endPos);
void cutText (in long startPos, in long endPos);
void deleteText (in long startPos, in long endPos);
void pasteText (in long position);
};
/*
Assumptions:
selectAttributes method takes an nsISupports parameter.
'set' methods throw exception on failure.
'wstring' inputs are potentially multibyte (UTF-16 for
instance); 'string' and UTF-8 may be a better choice.
*/

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bill Haneman (bill.haneman@sun.com)
* John Gaunt (jgaunt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIURI;
interface nsIAccessible;
[scriptable, uuid(a492c7d6-1dd1-11b2-9bc0-80614884799a)]
interface nsIAccessibleHyperLink : nsISupports
{
readonly attribute long anchors;
readonly attribute long startIndex;
readonly attribute long endIndex;
nsIURI getURI (in long i);
nsIAccessible getObject (in long i);
boolean isValid ();
boolean isSelected ();
};
/*
Assumptions:
The object associated with object or anchor index
is an nsIAccessible.
A URI can be represented by the nsIURI interface
(or nsIURL interface).
Note that an object which supports nsIAccessibleHyperlink
does *not* generally implement nsIAccessible, unlike the
case of the other nsiAccessible* interfaces in this directory.
Aaron: would the nsISupports return from
getObject be queryable for nsIURI and nsIURL directly?
*/

View File

@@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bill Haneman (bill.haneman@sun.com)
* Paul Sandoz (paul.sandoz@sun.com)
* John Gaunt (jgaunt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIAccessibleHyperLink.idl"
[scriptable, uuid(8f18d922-1dd2-11b2-82ea-829b78a44413)]
interface nsIAccessibleHyperText : nsISupports
{
readonly attribute long links;
nsIAccessibleHyperLink getLink (in long index);
long getLinkIndex (in long charIndex);
long getSelectedLinkIndex ();
};

View File

@@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul Sandoz (paul.sandoz@sun.com)
* Bill Haneman (bill.haneman@sun.com)
* John Gaunt (jgaunt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIAccessible;
[scriptable, uuid(0A7E98A9-CA7D-42F0-BFE1-2CFC35256038)]
interface nsIAccessibleTable : nsISupports
{
attribute nsIAccessible caption;
attribute AString summary;
readonly attribute long columns;
readonly attribute nsIAccessibleTable columnHeader;
readonly attribute long rows;
readonly attribute nsIAccessibleTable rowHeader;
void getSelectedColumns (out unsigned long columnsSize,
[retval, array, size_is(columnsSize)] out long columns);
void getSelectedRows (out unsigned long rowsSize,
[retval, array, size_is(rowsSize)] out long rows);
/**
* gets a cell
*/
nsIAccessible cellRefAt (in long row, in long column);
/**
* get an index
*/
long getIndexAt (in long row, in long column);
long getColumnAtIndex (in long index);
long getRowAtIndex (in long index);
long getColumnExtentAt (in long row, in long column);
long getRowExtentAt (in long row, in long column);
AString getColumnDescription (in long column);
AString getRowDescription (in long row);
boolean isColumnSelected (in long column);
boolean isRowSelected (in long row);
boolean isCellSelected (in long row, in long column);
};

View File

@@ -0,0 +1,144 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul Sandoz (paul.sandoz@sun.com)
* Bill Haneman (bill.haneman@sun.com)
* John Gaunt (jgaunt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
typedef long nsAccessibleTextBoundary;
typedef long nsAccessibleCoordType;
[scriptable, uuid(E44D3FA6-9CB2-432A-8BDB-69D72B6ADA00)]
interface nsIAccessibleText : nsISupports
{
const nsAccessibleTextBoundary BOUNDARY_CHAR = 0;
const nsAccessibleTextBoundary BOUNDARY_WORD_START = 1;
const nsAccessibleTextBoundary BOUNDARY_WORD_END = 2;
const nsAccessibleTextBoundary BOUNDARY_SENTENCE_START = 3;
const nsAccessibleTextBoundary BOUNDARY_SENTENCE_END = 4;
const nsAccessibleTextBoundary BOUNDARY_LINE_START = 5;
const nsAccessibleTextBoundary BOUNDARY_LINE_END = 6;
const nsAccessibleTextBoundary BOUNDARY_ATTRIBUTE_RANGE = 7;
const nsAccessibleCoordType COORD_TYPE_SCREEN = 0;
const nsAccessibleCoordType COORD_TYPE_WINDOW = 1;
attribute long caretOffset;
readonly attribute long characterCount;
readonly attribute long selectionCount;
/**
* String methods may need to return multibyte-encoded strings,
* since some locales can't be encoded using 16-bit chars.
* So the methods below might return UTF-16 strings, or they could
* return "string" values which are UTF-8.
*/
AString getText (in long startOffset, in long endOffset);
AString getTextAfterOffset (in long offset,
in nsAccessibleTextBoundary boundaryType,
out long startOffset,
out long endOffset);
AString getTextAtOffset (in long offset,
in nsAccessibleTextBoundary boundaryType,
out long startOffset,
out long endOffset);
AString getTextBeforeOffset (in long offset,
in nsAccessibleTextBoundary boundaryType,
out long startOffset,
out long endOffset);
/**
* It would be better to return an unsigned long here,
* to allow unicode chars > 16 bits
*/
wchar getCharacterAtOffset (in long offset);
nsISupports getAttributeRange (in long offset,
out long rangeStartOffset,
out long rangeEndOffset);
void getCharacterExtents (in long offset,
out long x,
out long y,
out long width,
out long height,
in nsAccessibleCoordType coordType);
long getOffsetAtPoint (in long x, in long y,
in nsAccessibleCoordType coordType);
void getSelectionBounds (in long selectionNum,
out long startOffset,
out long endOffset);
void setSelectionBounds (in long selectionNum,
in long startOffset,
in long endOffset);
void addSelection (in long startOffset, in long endOffset);
void removeSelection (in long selectionNum);
};
/*
Assumptions:
Using wstring (UCS2) instead of string encoded in UTF-8.
Multibyte encodings (or at least potentially multi-byte
encodings) would be preferred for the reasons cited above.
The following methods will throw an exception on failure
(since not every text component will allow every operation):
setSelectionBounds, addSelection, removeSelection, setCaretOffset.
getRangeAttributes defined to return an nsISupports
interface instead of a pango specific data structure.
It may be that some other return type is more appropriate
for mozilla text attributes.
we assume that all text components support the idea of
a caret offset, whether visible or "virtual". If this
isn't the case, caretOffset can be made readonly and
a setCaretOffset method provided which throws an exception
on failure (as with *selection methods above).
*/

View File

@@ -0,0 +1,74 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* John Gaunt (jgaunt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(F4ABBC2F-0F28-47DC-A9E9-F7A1719AB2BE)]
interface nsIAccessibleValue : nsISupports
{
readonly attribute double maximumValue;
readonly attribute double minimumValue;
readonly attribute double currentValue;
/**
* We want to be able to return a success condition of the value
* getting set. ie if the value is not within the interval of
* minimumValue-maximumValue
*/
boolean setCurrentValue (in double value);
};
/*
Assumptions:
The attribute currentValue will throw an exception
if it cannot be set i.e. if the value is not a
member of the interval.
This may not be the 'desired' behaviour given gObject
equivalent. Thus it could be changed to be:
readonly attribute double currentValue;
boolean setCurrentValue (double long value);
GValue can represent many basic types.
Since this interface is designed to represent
an interval and a member of double should
cover the cases of char int and float.
*/

Binary file not shown.

View File

@@ -0,0 +1,3 @@
; uncomment the define below if your product and locale
; can do the uninstall survey. see SURVEY_TEXT and SurveyURL
!define DO_UNINSTALL_SURVEY

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
/* $Id: cairo-analysis-surface-private.h,v 1.1 2006-06-05 23:16:24 vladimir%pobox.com Exp $
*
* 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 pixman_region16_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
cairo_private pixman_region16_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
cairo_private cairo_bool_t
_cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported);
#endif /* CAIRO_ANALYSIS_SURFACE_H */

View File

@@ -0,0 +1,259 @@
/*
* Copyright © 2006 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>
*/
#include "cairoint.h"
#include "cairo-analysis-surface-private.h"
#include "cairo-paginated-surface-private.h"
typedef struct {
cairo_surface_t base;
int width;
int height;
cairo_surface_t *target;
cairo_bool_t fallback;
} cairo_analysis_surface_t;
static cairo_int_status_t
_cairo_analysis_surface_get_extents (void *abstract_surface,
cairo_rectangle_fixed_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;
if (!surface->target->backend->paint)
status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->paint) (surface->target, op,
source);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
}
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_status_t status;
if (!surface->target->backend->mask)
status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->mask) (surface->target, op,
source, mask);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
}
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;
if (!surface->target->backend->stroke)
status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->stroke) (surface->target, op,
source, path, style,
ctm, ctm_inverse,
tolerance, antialias);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
}
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;
if (!surface->target->backend->fill)
status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->fill) (surface->target, op,
source, path, fill_rule,
tolerance, antialias);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
}
return status;
}
static cairo_int_status_t
_cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *source,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status;
if (!surface->target->backend->show_glyphs)
status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->show_glyphs) (surface->target, op,
source,
glyphs, num_glyphs,
scaled_font);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
}
return status;
}
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
NULL, /* create_similar */
NULL, /* finish_surface */
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 */
NULL, /* 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 */
};
cairo_private cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t *target,
int width,
int height)
{
cairo_analysis_surface_t *surface;
surface = malloc (sizeof (cairo_analysis_surface_t));
if (surface == NULL)
goto FAIL;
/* 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;
surface->target = target;
surface->fallback = FALSE;
return &surface->base;
FAIL:
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
cairo_private pixman_region16_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
{
/* XXX */
return NULL;
}
cairo_private pixman_region16_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
{
/* XXX */
return NULL;
}
cairo_private 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->fallback;
}

View File

@@ -0,0 +1,130 @@
/* 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 cairo_output_stream.c as distributed with 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"
typedef struct _cairo_base85_stream {
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 (void *closure,
const unsigned char *data,
unsigned int length)
{
cairo_base85_stream_t *stream = closure;
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 (void *closure)
{
cairo_status_t status;
cairo_base85_stream_t *stream = closure;
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, "~>");
status = _cairo_output_stream_get_status (stream->output);
free (stream);
return status;
}
cairo_output_stream_t *
_cairo_base85_stream_create (cairo_output_stream_t *output)
{
cairo_base85_stream_t *stream;
stream = malloc (sizeof (cairo_base85_stream_t));
if (stream == NULL)
return (cairo_output_stream_t *) &cairo_output_stream_nil;
stream->output = output;
stream->pending = 0;
return _cairo_output_stream_create (_cairo_base85_stream_write,
_cairo_base85_stream_close,
stream);
}

View File

@@ -0,0 +1,119 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2006 Keith Packard
* 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>
* Keith Packard <keithp@keithp.com>
*/
#include "cairoint.h"
/* The analysis here assumes destination alpha semantics (that is
* CAIRO_CONTENT_COLOR_ALPHA). More things can be considered opaque
* otherwise (CAIRO_CONTENT_COLOR) so we'll probably want to add a
* cairo_content_t parameter to this function
*
* We also need a definition of what "opaque" means. Is it, "does not
* requiring 'knowing' the original contents of destination, nor does
* it set the destination alpha to anything but 1.0" ?
*/
cairo_bool_t
_cairo_operator_always_opaque (cairo_operator_t op)
{
switch (op) {
case CAIRO_OPERATOR_CLEAR:
return FALSE;
case CAIRO_OPERATOR_SOURCE:
return FALSE;
case CAIRO_OPERATOR_OVER:
case CAIRO_OPERATOR_IN:
case CAIRO_OPERATOR_OUT:
case CAIRO_OPERATOR_ATOP:
return FALSE;
case CAIRO_OPERATOR_DEST:
return TRUE;
case CAIRO_OPERATOR_DEST_OVER:
case CAIRO_OPERATOR_DEST_IN:
case CAIRO_OPERATOR_DEST_OUT:
case CAIRO_OPERATOR_DEST_ATOP:
return FALSE;
case CAIRO_OPERATOR_XOR:
case CAIRO_OPERATOR_ADD:
case CAIRO_OPERATOR_SATURATE:
return FALSE;
}
return FALSE;
}
/* As above, we'll probably want to add a cairo_content_t parameter to
* this function
*
* We also need a definition of what "translucent" means.
*/
cairo_bool_t
_cairo_operator_always_translucent (cairo_operator_t op)
{
switch (op) {
case CAIRO_OPERATOR_CLEAR:
return TRUE;
case CAIRO_OPERATOR_SOURCE:
return FALSE;
case CAIRO_OPERATOR_OVER:
case CAIRO_OPERATOR_IN:
case CAIRO_OPERATOR_OUT:
case CAIRO_OPERATOR_ATOP:
return FALSE;
case CAIRO_OPERATOR_DEST:
return FALSE;
case CAIRO_OPERATOR_DEST_OVER:
case CAIRO_OPERATOR_DEST_IN:
case CAIRO_OPERATOR_DEST_OUT:
case CAIRO_OPERATOR_DEST_ATOP:
return FALSE;
case CAIRO_OPERATOR_XOR:
case CAIRO_OPERATOR_ADD:
case CAIRO_OPERATOR_SATURATE:
return TRUE;
}
return TRUE;
}

View File

@@ -0,0 +1,76 @@
/* 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>
*/
#ifndef CAIRO_PDF_TEST_H
#define CAIRO_PDF_TEST_H
#include <cairo.h>
#if CAIRO_HAS_PDF_SURFACE
#include <cairo-pdf.h>
CAIRO_BEGIN_DECLS
struct _cairo_path_fixed;
struct _cairo_traps;
struct _cairo_trapezoid;
struct _cairo_clip;
void
cairo_pdf_test_force_fallbacks (void);
void
cairo_debug_dump_clip (struct _cairo_clip *clip,
FILE *fp);
void
cairo_debug_dump_path (struct _cairo_path_fixed *path,
FILE *fp);
void
cairo_debug_dump_traps (struct _cairo_traps *traps,
FILE *fp);
void
cairo_debug_dump_trapezoid_array (struct _cairo_trapezoid *traps,
int num_traps,
FILE *fp);
CAIRO_END_DECLS
#endif /* CAIRO_HAS_PDF_SURFACE */
#endif /* CAIRO_PDF_TEST_H */

View File

@@ -0,0 +1,182 @@
/* 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>
*/
#ifndef CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H
#define CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H
#include "cairoint.h"
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
typedef struct _cairo_scaled_font_subset {
cairo_scaled_font_t *scaled_font;
unsigned int font_id;
unsigned int subset_id;
/* Index of glyphs array is subset_glyph_index.
* Value of glyphs array is scaled_font_glyph_index.
*/
unsigned long *glyphs;
int num_glyphs;
} cairo_scaled_font_subset_t;
/**
* _cairo_scaled_font_subsets_create:
* @max_glyphs_per_subset: the maximum number of glyphs that should
* appear in any subset. A value of 0 indicates that there is no limit
* to the number of glyphs per subset.
*
* Create a new #cairo_scaled_font_subsets_t object which can be used
* to create subsets of any number of cairo_scaled_font_t
* objects. This allows the (arbitrarily large and sparse) glyph
* indices of a cairo_scaled_font to be mapped to one or more font
* subsets with glyph indices packed into the range
* [0 .. max_glyphs_per_subset).
*
* Return value: a pointer to the newly creates font subsets. The
* caller owns this object and should call
* _cairo_scaled_font_subsets_destroy() when done with it.
**/
cairo_private cairo_scaled_font_subsets_t *
_cairo_scaled_font_subsets_create (int max_glyphs_per_subset);
/**
* _cairo_scaled_font_subsets_destroy:
* @font_subsets: a #cairo_scaled_font_subsets_t object to be destroyed
*
* Destroys @font_subsets and all resources associated with it.
**/
cairo_private void
_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
/**
* _cairo_scaled_font_subsets_map_glyph:
* @font_subsets: a #cairo_scaled_font_subsets_t
* @scaled_font: the font of the glyph to be mapped
* @scaled_font_glyph_index: the index of the glyph to be mapped
* @font_id_ret: return value giving the font ID of the mapped glyph
* @subset_id_ret: return value giving the subset ID of the mapped glyph within the @font_id_ret
* @subset_glyph_index_ret: return value giving the index of the mapped glyph within the @subset_id_ret subset
*
* Map a glyph from a #cairo_scaled_font to a new index within a
* subset of that font. The mapping performed is from the tuple:
*
* (scaled_font, scaled_font_glyph_index)
*
* to the tuple:
*
* (font_id, subset_id, subset_glyph_index)
*
* This mapping is 1:1. If the input tuple has previously mapped, the
* the output tuple previously returned will be returned again.
*
* Otherwise, the return tuple will be constructed as follows:
*
* 1) There is a 1:1 correspondence between the input scaled_font
* value and the output font_id value. If no mapping has been
* previously performed with the scaled_font value then the
* smallest unused font_id value will be returned.
*
* 2) Within the set of output tuples of the same font_id value the
* smallest value of subset_id will be returned such that
* subset_glyph_index does not exceed max_glyphs_per_subset (as
* passed to _cairo_scaled_font_subsets_create()) and that the
* resulting tuple is unique.
*
* 3) The smallest value of subset_glyph_index is returned such that
* the resulting tuple is unique.
*
* The net result is that any #cairo_scaled_font_t will be represented
* by one or more font subsets. Each subset is effectively a tuple of
* (scaled_font, font_id, subset_id) and within each subset there
* exists a mapping of scaled_glyph_font_index to subset_glyph_index.
*
* This final description of a font subset is the same representation
* used by #cairo_scaled_font_subset_t as provided by
* _cairo_scaled_font_subsets_foreach.
*
* Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero
* value indicating an error. Possible errors include
* CAIRO_STATUS_NO_MEMORY.
**/
cairo_private cairo_status_t
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets,
cairo_scaled_font_t *scaled_font,
unsigned long scaled_font_glyph_index,
unsigned int *font_id_ret,
unsigned int *subset_id_ret,
unsigned int *subset_glyph_index_ret);
typedef void
(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset,
void *closure);
/**
* _cairo_scaled_font_subsets_foreach:
* @font_subsets: a #cairo_scaled_font_subsets_t
* @font_subset_callback: a function to be called for each font subset
* @closure: closure data for the callback function
*
* Iterate over each unique font subset as created by calls to
* _cairo_scaled_font_subsets_map_glyph(). A subset is determined by
* unique pairs of (font_id, subset_id) as returned by
* _cairo_scaled_font_subsets_map_glyph().
*
* For each subset, @font_subset_callback will be called and will be
* provided with both a #cairo_scaled_font_subset_t object containing
* all the glyphs in the subset as well as the value of @closure.
*
* The #cairo_scaled_font_subset_t object contains the scaled_font,
* the font_id, and the subset_id corresponding to all glyphs
* belonging to the subset. In addition, it contains an array providing
* a mapping between subset glyph indices and the original scaled font
* glyph indices.
*
* The index of the array corresponds to subset_glyph_index values
* returned by _cairo_scaled_font_subsets_map_glyph() while the
* values of the array correspond to the scaled_font_glyph_index
* values passed as input to the same function.
*
* Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero
* value indicating an error. Possible errors include
* CAIRO_STATUS_NO_MEMORY.
**/
cairo_private cairo_status_t
_cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets,
cairo_scaled_font_subset_callback_func_t font_subset_callback,
void *closure);
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */

View File

@@ -0,0 +1,385 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2003 University of Southern California
* Copyright © 2005 Red Hat, Inc
* Copyright © 2006 Keith Packard
* 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>
* Kristian Høgsberg <krh@redhat.com>
* Keith Packard <keithp@keithp.com>
*/
#include "cairoint.h"
#include "cairo-scaled-font-subsets-private.h"
struct _cairo_scaled_font_subsets {
int max_glyphs_per_subset_limit;
int max_glyphs_per_subset_used;
int num_sub_fonts;
cairo_hash_table_t *sub_fonts;
};
typedef struct _cairo_sub_font {
cairo_hash_entry_t base;
cairo_scaled_font_subsets_t *parent;
cairo_scaled_font_t *scaled_font;
unsigned int font_id;
int current_subset;
int num_glyphs_in_current_subset;
int max_glyphs_per_subset;
cairo_hash_table_t *sub_font_glyphs;
} cairo_sub_font_t;
typedef struct _cairo_sub_font_glyph {
cairo_hash_entry_t base;
unsigned int subset_id;
unsigned int subset_glyph_index;
} cairo_sub_font_glyph_t;
typedef struct _cairo_sub_font_collection {
unsigned long *glyphs; /* scaled_font_glyph_index */
int glyphs_size;
int max_glyph;
int num_glyphs;
unsigned int subset_id;
cairo_scaled_font_subset_callback_func_t font_subset_callback;
void *font_subset_callback_closure;
} cairo_sub_font_collection_t;
static void
_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph,
unsigned long scaled_font_glyph_index)
{
sub_font_glyph->base.hash = scaled_font_glyph_index;
}
static cairo_bool_t
_cairo_sub_font_glyphs_equal (const void *key_a, const void *key_b)
{
const cairo_sub_font_glyph_t *sub_font_glyph_a = key_a;
const cairo_sub_font_glyph_t *sub_font_glyph_b = key_b;
return sub_font_glyph_a->base.hash == sub_font_glyph_b->base.hash;
}
static cairo_sub_font_glyph_t *
_cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
unsigned int subset_id,
unsigned int subset_glyph_index)
{
cairo_sub_font_glyph_t *sub_font_glyph;
sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t));
if (sub_font_glyph == NULL)
return NULL;
_cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index);
sub_font_glyph->subset_id = subset_id;
sub_font_glyph->subset_glyph_index = subset_glyph_index;
return sub_font_glyph;
}
static void
_cairo_sub_font_glyph_destroy (cairo_sub_font_glyph_t *sub_font_glyph)
{
free (sub_font_glyph);
}
static void
_cairo_sub_font_glyph_pluck (void *entry, void *closure)
{
cairo_sub_font_glyph_t *sub_font_glyph = entry;
cairo_hash_table_t *sub_font_glyphs = closure;
_cairo_hash_table_remove (sub_font_glyphs, &sub_font_glyph->base);
_cairo_sub_font_glyph_destroy (sub_font_glyph);
}
static void
_cairo_sub_font_glyph_collect (void *entry, void *closure)
{
cairo_sub_font_glyph_t *sub_font_glyph = entry;
cairo_sub_font_collection_t *collection = closure;
unsigned long scaled_font_glyph_index;
unsigned int subset_glyph_index;
if (sub_font_glyph->subset_id != collection->subset_id)
return;
scaled_font_glyph_index = sub_font_glyph->base.hash;
subset_glyph_index = sub_font_glyph->subset_glyph_index;
/* Ensure we don't exceed the allocated bounds. */
assert (subset_glyph_index < collection->glyphs_size);
collection->glyphs[subset_glyph_index] = scaled_font_glyph_index;
if (subset_glyph_index > collection->max_glyph)
collection->max_glyph = subset_glyph_index;
collection->num_glyphs++;
}
static cairo_bool_t
_cairo_sub_fonts_equal (const void *key_a, const void *key_b)
{
const cairo_sub_font_t *sub_font_a = key_a;
const cairo_sub_font_t *sub_font_b = key_b;
return sub_font_a->scaled_font == sub_font_b->scaled_font;
}
static void
_cairo_sub_font_init_key (cairo_sub_font_t *sub_font,
cairo_scaled_font_t *scaled_font)
{
sub_font->base.hash = (unsigned long) scaled_font;
sub_font->scaled_font = scaled_font;
}
static cairo_sub_font_t *
_cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_scaled_font_t *scaled_font,
unsigned int font_id,
int max_glyphs_per_subset)
{
cairo_sub_font_t *sub_font;
sub_font = malloc (sizeof (cairo_sub_font_t));
if (sub_font == NULL)
return NULL;
_cairo_sub_font_init_key (sub_font, scaled_font);
sub_font->parent = parent;
sub_font->scaled_font = cairo_scaled_font_reference (scaled_font);
sub_font->font_id = font_id;
sub_font->current_subset = 0;
sub_font->num_glyphs_in_current_subset = 0;
sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
if (! sub_font->sub_font_glyphs) {
free (sub_font);
return NULL;
}
return sub_font;
}
static void
_cairo_sub_font_destroy (cairo_sub_font_t *sub_font)
{
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_cairo_sub_font_glyph_pluck,
sub_font->sub_font_glyphs);
_cairo_hash_table_destroy (sub_font->sub_font_glyphs);
cairo_scaled_font_destroy (sub_font->scaled_font);
free (sub_font);
}
static void
_cairo_sub_font_pluck (void *entry, void *closure)
{
cairo_sub_font_t *sub_font = entry;
cairo_hash_table_t *sub_fonts = closure;
_cairo_hash_table_remove (sub_fonts, &sub_font->base);
_cairo_sub_font_destroy (sub_font);
}
static cairo_status_t
_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
unsigned long scaled_font_glyph_index,
unsigned int *subset_id,
unsigned int *subset_glyph_index)
{
cairo_sub_font_glyph_t key, *sub_font_glyph;
cairo_status_t status;
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
(cairo_hash_entry_t **) &sub_font_glyph))
{
if (sub_font->max_glyphs_per_subset &&
sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
{
sub_font->current_subset++;
sub_font->num_glyphs_in_current_subset = 0;
}
sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
sub_font->current_subset,
sub_font->num_glyphs_in_current_subset++);
if (sub_font_glyph == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_subset_used)
sub_font->parent->max_glyphs_per_subset_used = sub_font->num_glyphs_in_current_subset;
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
if (status)
return status;
}
*subset_id = sub_font_glyph->subset_id;
*subset_glyph_index = sub_font_glyph->subset_glyph_index;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_sub_font_collect (void *entry, void *closure)
{
cairo_sub_font_t *sub_font = entry;
cairo_sub_font_collection_t *collection = closure;
cairo_scaled_font_subset_t subset;
int i;
for (i = 0; i <= sub_font->current_subset; i++) {
collection->subset_id = i;
collection->num_glyphs = 0;
collection->max_glyph = 0;
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_cairo_sub_font_glyph_collect, collection);
/* Ensure the resulting array has no uninitialized holes */
assert (collection->num_glyphs == collection->max_glyph + 1);
subset.scaled_font = sub_font->scaled_font;
subset.font_id = sub_font->font_id;
subset.subset_id = i;
subset.glyphs = collection->glyphs;
subset.num_glyphs = collection->num_glyphs;
(collection->font_subset_callback) (&subset,
collection->font_subset_callback_closure);
}
}
cairo_scaled_font_subsets_t *
_cairo_scaled_font_subsets_create (int max_glyphs_per_subset)
{
cairo_scaled_font_subsets_t *subsets;
subsets = malloc (sizeof (cairo_scaled_font_subsets_t));
if (subsets == NULL)
return NULL;
subsets->max_glyphs_per_subset_limit = max_glyphs_per_subset;
subsets->max_glyphs_per_subset_used = 0;
subsets->num_sub_fonts = 0;
subsets->sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal);
if (! subsets->sub_fonts) {
free (subsets);
return NULL;
}
return subsets;
}
void
_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets)
{
_cairo_hash_table_foreach (subsets->sub_fonts, _cairo_sub_font_pluck, subsets->sub_fonts);
_cairo_hash_table_destroy (subsets->sub_fonts);
free (subsets);
}
cairo_private cairo_status_t
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
cairo_scaled_font_t *scaled_font,
unsigned long scaled_font_glyph_index,
unsigned int *font_id,
unsigned int *subset_id,
unsigned int *subset_glyph_index)
{
cairo_sub_font_t key, *sub_font;
cairo_status_t status;
_cairo_sub_font_init_key (&key, scaled_font);
if (! _cairo_hash_table_lookup (subsets->sub_fonts, &key.base,
(cairo_hash_entry_t **) &sub_font))
{
sub_font = _cairo_sub_font_create (subsets, scaled_font,
subsets->num_sub_fonts++,
subsets->max_glyphs_per_subset_limit);
if (sub_font == NULL)
return CAIRO_STATUS_NO_MEMORY;
status = _cairo_hash_table_insert (subsets->sub_fonts,
&sub_font->base);
if (status)
return status;
}
*font_id = sub_font->font_id;
return _cairo_sub_font_map_glyph (sub_font, scaled_font_glyph_index,
subset_id, subset_glyph_index);
}
cairo_private cairo_status_t
_cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets,
cairo_scaled_font_subset_callback_func_t font_subset_callback,
void *closure)
{
cairo_sub_font_collection_t collection;
collection.glyphs_size = font_subsets->max_glyphs_per_subset_used;
collection.glyphs = malloc (collection.glyphs_size * sizeof(unsigned long));
if (collection.glyphs == NULL)
return CAIRO_STATUS_NO_MEMORY;
collection.font_subset_callback = font_subset_callback;
collection.font_subset_callback_closure = closure;
_cairo_hash_table_foreach (font_subsets->sub_fonts,
_cairo_sub_font_collect, &collection);
free (collection.glyphs);
return CAIRO_STATUS_SUCCESS;
}

View File

@@ -0,0 +1,459 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsUnicodeRange.h"
// This table depends on unicode range definitions.
// Each item's index must correspond unicode range value
// eg. x-cyrillic = LangGroupTable[kRangeCyrillic]
static const char *gUnicodeRangeToLangGroupTable[] =
{
"x-cyrillic",
"el",
"tr",
"he",
"ar",
"x-baltic",
"th",
"ko",
"ja",
"zh-CN",
"zh-TW",
"x-devanagari",
"x-tamil",
"x-armn",
"x-beng",
"x-cans",
"x-ethi",
"x-geor",
"x-gujr",
"x-guru",
"x-khmr",
"x-mlym"
};
/**********************************************************************
* Unicode subranges as defined in unicode 3.0
* x-western, x-central-euro, tr, x-baltic -> latin
* 0000 - 036f
* 1e00 - 1eff
* 2000 - 206f (general punctuation)
* 20a0 - 20cf (currency symbols)
* 2100 - 214f (letterlike symbols)
* 2150 - 218f (Number Forms)
* el -> greek
* 0370 - 03ff
* 1f00 - 1fff
* x-cyrillic -> cyrillic
* 0400 - 04ff
* he -> hebrew
* 0590 - 05ff
* ar -> arabic
* 0600 - 06ff
* fb50 - fdff (arabic presentation forms)
* fe70 - feff (arabic presentation forms b)
* th - thai
* 0e00 - 0e7f
* ko -> korean
* ac00 - d7af (hangul Syllables)
* 1100 - 11ff (jamo)
* 3130 - 318f (hangul compatibility jamo)
* ja
* 3040 - 309f (hiragana)
* 30a0 - 30ff (katakana)
* zh-CN
* zh-TW
*
* CJK
* 3100 - 312f (bopomofo)
* 31a0 - 31bf (bopomofo extended)
* 3000 - 303f (CJK Symbols and Punctuation)
* 2e80 - 2eff (CJK radicals supplement)
* 2f00 - 2fdf (Kangxi Radicals)
* 2ff0 - 2fff (Ideographic Description Characters)
* 3190 - 319f (kanbun)
* 3200 - 32ff (Enclosed CJK letters and Months)
* 3300 - 33ff (CJK compatibility)
* 3400 - 4dbf (CJK Unified Ideographs Extension A)
* 4e00 - 9faf (CJK Unified Ideographs)
* f900 - fa5f (CJK Compatibility Ideographs)
* fe30 - fe4f (CJK compatibility Forms)
* ff00 - ffef (halfwidth and fullwidth forms)
*
* Armenian
* 0530 - 058f
* Sriac
* 0700 - 074f
* Thaana
* 0780 - 07bf
* Devanagari
* 0900 - 097f
* Bengali
* 0980 - 09ff
* Gurmukhi
* 0a00 - 0a7f
* Gujarati
* 0a80 - 0aff
* Oriya
* 0b00 - 0b7f
* Tamil
* 0b80 - 0bff
* Telugu
* 0c00 - 0c7f
* Kannada
* 0c80 - 0cff
* Malayalam
* 0d00 - 0d7f
* Sinhala
* 0d80 - 0def
* Lao
* 0e80 - 0eff
* Tibetan
* 0f00 - 0fbf
* Myanmar
* 1000 - 109f
* Georgian
* 10a0 - 10ff
* Ethiopic
* 1200 - 137f
* Cherokee
* 13a0 - 13ff
* Canadian Aboriginal Syllabics
* 1400 - 167f
* Ogham
* 1680 - 169f
* Runic
* 16a0 - 16ff
* Khmer
* 1780 - 17ff
* Mongolian
* 1800 - 18af
* Misc - superscripts and subscripts
* 2070 - 209f
* Misc - Combining Diacritical Marks for Symbols
* 20d0 - 20ff
* Misc - Arrows
* 2190 - 21ff
* Misc - Mathematical Operators
* 2200 - 22ff
* Misc - Miscellaneous Technical
* 2300 - 23ff
* Misc - Control picture
* 2400 - 243f
* Misc - Optical character recognition
* 2440 - 2450
* Misc - Enclose Alphanumerics
* 2460 - 24ff
* Misc - Box Drawing
* 2500 - 257f
* Misc - Block Elements
* 2580 - 259f
* Misc - Geometric Shapes
* 25a0 - 25ff
* Misc - Miscellaneous Symbols
* 2600 - 267f
* Misc - Dingbats
* 2700 - 27bf
* Misc - Braille Patterns
* 2800 - 28ff
* Yi Syllables
* a000 - a48f
* Yi radicals
* a490 - a4cf
* Alphabetic Presentation Forms
* fb00 - fb4f
* Misc - Combining half Marks
* fe20 - fe2f
* Misc - small form variants
* fe50 - fe6f
* Misc - Specials
* fff0 - ffff
*********************************************************************/
#define NUM_OF_SUBTABLES 9
#define SUBTABLE_SIZE 16
static const PRUint8 gUnicodeSubrangeTable[NUM_OF_SUBTABLES][SUBTABLE_SIZE] =
{
{ // table for X---
kRangeTableBase+1, //u0xxx
kRangeTableBase+2, //u1xxx
kRangeTableBase+3, //u2xxx
kRangeSetCJK, //u3xxx
kRangeSetCJK, //u4xxx
kRangeSetCJK, //u5xxx
kRangeSetCJK, //u6xxx
kRangeSetCJK, //u7xxx
kRangeSetCJK, //u8xxx
kRangeSetCJK, //u9xxx
kRangeTableBase+4, //uaxxx
kRangeKorean, //ubxxx
kRangeKorean, //ucxxx
kRangeTableBase+5, //udxxx
kRangePrivate, //uexxx
kRangeTableBase+6 //ufxxx
},
{ //table for 0X--
kRangeSetLatin, //u00xx
kRangeSetLatin, //u01xx
kRangeSetLatin, //u02xx
kRangeGreek, //u03xx XXX 0300-036f is in fact kRangeCombiningDiacriticalMarks
kRangeCyrillic, //u04xx
kRangeTableBase+7, //u05xx, includes Cyrillic supplement, Hebrew, and Armenian
kRangeArabic, //u06xx
kRangeTertiaryTable, //u07xx
kRangeUnassigned, //u08xx
kRangeTertiaryTable, //u09xx
kRangeTertiaryTable, //u0axx
kRangeTertiaryTable, //u0bxx
kRangeTertiaryTable, //u0cxx
kRangeTertiaryTable, //u0dxx
kRangeTertiaryTable, //u0exx
kRangeTibetan, //u0fxx
},
{ //table for 1x--
kRangeTertiaryTable, //u10xx
kRangeKorean, //u11xx
kRangeEthiopic, //u12xx
kRangeTertiaryTable, //u13xx
kRangeCanadian, //u14xx
kRangeCanadian, //u15xx
kRangeTertiaryTable, //u16xx
kRangeKhmer, //u17xx
kRangeMongolian, //u18xx
kRangeUnassigned, //u19xx
kRangeUnassigned, //u1axx
kRangeUnassigned, //u1bxx
kRangeUnassigned, //u1cxx
kRangeUnassigned, //u1dxx
kRangeSetLatin, //u1exx
kRangeGreek, //u1fxx
},
{ //table for 2x--
kRangeSetLatin, //u20xx
kRangeSetLatin, //u21xx
kRangeMathOperators, //u22xx
kRangeMiscTechnical, //u23xx
kRangeControlOpticalEnclose, //u24xx
kRangeBoxBlockGeometrics, //u25xx
kRangeMiscSymbols, //u26xx
kRangeDingbats, //u27xx
kRangeBraillePattern, //u28xx
kRangeUnassigned, //u29xx
kRangeUnassigned, //u2axx
kRangeUnassigned, //u2bxx
kRangeUnassigned, //u2cxx
kRangeUnassigned, //u2dxx
kRangeSetCJK, //u2exx
kRangeSetCJK, //u2fxx
},
{ //table for ax--
kRangeYi, //ua0xx
kRangeYi, //ua1xx
kRangeYi, //ua2xx
kRangeYi, //ua3xx
kRangeYi, //ua4xx
kRangeUnassigned, //ua5xx
kRangeUnassigned, //ua6xx
kRangeUnassigned, //ua7xx
kRangeUnassigned, //ua8xx
kRangeUnassigned, //ua9xx
kRangeUnassigned, //uaaxx
kRangeUnassigned, //uabxx
kRangeKorean, //uacxx
kRangeKorean, //uadxx
kRangeKorean, //uaexx
kRangeKorean, //uafxx
},
{ //table for dx--
kRangeKorean, //ud0xx
kRangeKorean, //ud1xx
kRangeKorean, //ud2xx
kRangeKorean, //ud3xx
kRangeKorean, //ud4xx
kRangeKorean, //ud5xx
kRangeKorean, //ud6xx
kRangeKorean, //ud7xx
kRangeSurrogate, //ud8xx
kRangeSurrogate, //ud9xx
kRangeSurrogate, //udaxx
kRangeSurrogate, //udbxx
kRangeSurrogate, //udcxx
kRangeSurrogate, //uddxx
kRangeSurrogate, //udexx
kRangeSurrogate, //udfxx
},
{ // table for fx--
kRangePrivate, //uf0xx
kRangePrivate, //uf1xx
kRangePrivate, //uf2xx
kRangePrivate, //uf3xx
kRangePrivate, //uf4xx
kRangePrivate, //uf5xx
kRangePrivate, //uf6xx
kRangePrivate, //uf7xx
kRangePrivate, //uf8xx
kRangeSetCJK, //uf9xx
kRangeSetCJK, //ufaxx
kRangeArabic, //ufbxx, includes alphabic presentation form
kRangeArabic, //ufcxx
kRangeArabic, //ufdxx
kRangeArabic, //ufexx, includes Combining half marks,
// CJK compatibility forms,
// CJK compatibility forms,
// small form variants
kRangeTableBase+8, //uffxx, halfwidth and fullwidth forms, includes Specials
},
{ //table for 0x0500 - 0x05ff
kRangeCyrillic, //u050x
kRangeCyrillic, //u051x
kRangeCyrillic, //u052x
kRangeArmenian, //u053x
kRangeArmenian, //u054x
kRangeArmenian, //u055x
kRangeArmenian, //u056x
kRangeArmenian, //u057x
kRangeArmenian, //u058x
kRangeHebrew, //u059x
kRangeHebrew, //u05ax
kRangeHebrew, //u05bx
kRangeHebrew, //u05cx
kRangeHebrew, //u05dx
kRangeHebrew, //u05ex
kRangeHebrew, //u05fx
},
{ //table for 0xff00 - 0xffff
kRangeSetCJK, //uff0x, fullwidth latin
kRangeSetCJK, //uff1x, fullwidth latin
kRangeSetCJK, //uff2x, fullwidth latin
kRangeSetCJK, //uff3x, fullwidth latin
kRangeSetCJK, //uff4x, fullwidth latin
kRangeSetCJK, //uff5x, fullwidth latin
kRangeSetCJK, //uff6x, halfwidth katakana
kRangeSetCJK, //uff7x, halfwidth katakana
kRangeSetCJK, //uff8x, halfwidth katakana
kRangeSetCJK, //uff9x, halfwidth katakana
kRangeSetCJK, //uffax, halfwidth hangul jamo
kRangeSetCJK, //uffbx, halfwidth hangul jamo
kRangeSetCJK, //uffcx, halfwidth hangul jamo
kRangeSetCJK, //uffdx, halfwidth hangul jamo
kRangeSetCJK, //uffex, fullwidth symbols
kRangeSpecials, //ufffx, Specials
},
};
// Most scripts between U+0700 and U+16FF are assigned a chunk of 128 (0x80)
// code points so that the number of entries in the tertiary range
// table for that range is obtained by dividing (0x1700 - 0x0700) by 128.
// Exceptions: Ethiopic, Tibetan, Hangul Jamo and Canadian aboriginal
// syllabaries take multiple chunks and Ogham and Runic share a single chunk.
#define TERTIARY_TABLE_SIZE ((0x1700 - 0x0700) / 0x80)
static const PRUint8 gUnicodeTertiaryRangeTable[TERTIARY_TABLE_SIZE] =
{ //table for 0x0700 - 0x1600
kRangeSyriac, //u070x
kRangeThaana, //u078x
kRangeUnassigned, //u080x place holder(resolved in the 2ndary tab.)
kRangeUnassigned, //u088x place holder(resolved in the 2ndary tab.)
kRangeDevanagari, //u090x
kRangeBengali, //u098x
kRangeGurmukhi, //u0a0x
kRangeGujarati, //u0a8x
kRangeOriya, //u0b0x
kRangeTamil, //u0b8x
kRangeTelugu, //u0c0x
kRangeKannada, //u0c8x
kRangeMalayalam, //u0d0x
kRangeSinhala, //u0d8x
kRangeThai, //u0e0x
kRangeLao, //u0e8x
kRangeTibetan, //u0f0x place holder(resolved in the 2ndary tab.)
kRangeTibetan, //u0f8x place holder(resolved in the 2ndary tab.)
kRangeMyanmar, //u100x
kRangeGeorgian, //u108x
kRangeKorean, //u110x place holder(resolved in the 2ndary tab.)
kRangeKorean, //u118x place holder(resolved in the 2ndary tab.)
kRangeEthiopic, //u120x place holder(resolved in the 2ndary tab.)
kRangeEthiopic, //u128x place holder(resolved in the 2ndary tab.)
kRangeEthiopic, //u130x
kRangeCherokee, //u138x
kRangeCanadian, //u140x place holder(resolved in the 2ndary tab.)
kRangeCanadian, //u148x place holder(resolved in the 2ndary tab.)
kRangeCanadian, //u150x place holder(resolved in the 2ndary tab.)
kRangeCanadian, //u158x place holder(resolved in the 2ndary tab.)
kRangeCanadian, //u160x
kRangeOghamRunic, //u168x this contains two scripts, Ogham & Runic
};
// A two level index is almost enough for locating a range, with the
// exception of u03xx and u05xx. Since we don't really care about range for
// combining diacritical marks in our font application, they are
// not discriminated further. But future adoption of this module for other use
// should be aware of this limitation. The implementation can be extended if
// there is such a need.
// For Indic, Southeast Asian scripts and some other scripts between
// U+0700 and U+16FF, it's extended to the third level.
PRUint32 FindCharUnicodeRange(PRUnichar ch)
{
PRUint32 range;
//search the first table
range = gUnicodeSubrangeTable[0][ch >> 12];
if (range < kRangeTableBase)
// we try to get a specific range
return range;
// otherwise, we have one more table to look at
range = gUnicodeSubrangeTable[range - kRangeTableBase][(ch & 0x0f00) >> 8];
if (range < kRangeTableBase)
return range;
if (range < kRangeTertiaryTable)
return gUnicodeSubrangeTable[range - kRangeTableBase][(ch & 0x00f0) >> 4];
// Yet another table to look at : U+0700 - U+16FF : 128 code point blocks
return gUnicodeTertiaryRangeTable[(ch - 0x0700) >> 7];
}
const char* LangGroupFromUnicodeRange(PRUint8 unicodeRange)
{
if (kRangeSpecificItemNum > unicodeRange)
return gUnicodeRangeToLangGroupTable[unicodeRange];
return nsnull;
}

View File

@@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
// The following constants define unicode subranges
// values below kRangeNum must be continuous so that we can map to
// lang group directly.
// all ranges we care about should be defined under 32, that allows
// us to store range using bits of a PRUint32
// frequently used range definitions
const PRUint8 kRangeCyrillic = 0;
const PRUint8 kRangeGreek = 1;
const PRUint8 kRangeTurkish = 2;
const PRUint8 kRangeHebrew = 3;
const PRUint8 kRangeArabic = 4;
const PRUint8 kRangeBaltic = 5;
const PRUint8 kRangeThai = 6;
const PRUint8 kRangeKorean = 7;
const PRUint8 kRangeJapanese = 8;
const PRUint8 kRangeSChinese = 9;
const PRUint8 kRangeTChinese = 10;
const PRUint8 kRangeDevanagari = 11;
const PRUint8 kRangeTamil = 12;
const PRUint8 kRangeArmenian = 13;
const PRUint8 kRangeBengali = 14;
const PRUint8 kRangeCanadian = 15;
const PRUint8 kRangeEthiopic = 16;
const PRUint8 kRangeGeorgian = 17;
const PRUint8 kRangeGujarati = 18;
const PRUint8 kRangeGurmukhi = 19;
const PRUint8 kRangeKhmer = 20;
const PRUint8 kRangeMalayalam = 21;
const PRUint8 kRangeSpecificItemNum = 22;
//range/rangeSet grow to this place 22-29
const PRUint8 kRangeSetStart = 30; // range set definition starts from here
const PRUint8 kRangeSetLatin = 30;
const PRUint8 kRangeSetCJK = 31;
const PRUint8 kRangeSetEnd = 31; // range set definition ends here
// less frequently used range definition
const PRUint8 kRangeSurrogate = 32;
const PRUint8 kRangePrivate = 33;
const PRUint8 kRangeMisc = 34;
const PRUint8 kRangeUnassigned = 35;
const PRUint8 kRangeSyriac = 36;
const PRUint8 kRangeThaana = 37;
const PRUint8 kRangeOriya = 38;
const PRUint8 kRangeTelugu = 39;
const PRUint8 kRangeKannada = 40;
const PRUint8 kRangeSinhala = 41;
const PRUint8 kRangeLao = 42;
const PRUint8 kRangeTibetan = 43;
const PRUint8 kRangeMyanmar = 44;
const PRUint8 kRangeCherokee = 45;
const PRUint8 kRangeOghamRunic = 46;
const PRUint8 kRangeMongolian = 47;
const PRUint8 kRangeMathOperators = 48;
const PRUint8 kRangeMiscTechnical = 49;
const PRUint8 kRangeControlOpticalEnclose = 50;
const PRUint8 kRangeBoxBlockGeometrics = 51;
const PRUint8 kRangeMiscSymbols = 52;
const PRUint8 kRangeDingbats = 53;
const PRUint8 kRangeBraillePattern = 54;
const PRUint8 kRangeYi = 55;
const PRUint8 kRangeCombiningDiacriticalMarks = 56;
const PRUint8 kRangeSpecials = 57;
const PRUint8 kRangeTableBase = 128; //values over 127 are reserved for internal use only
const PRUint8 kRangeTertiaryTable = 145; // leave room for 16 subtable
// indices (kRangeTableBase + 1 ..
// kRangeTableBase + 16)
PRUint32 FindCharUnicodeRange(PRUnichar ch);
const char* LangGroupFromUnicodeRange(PRUint8 unicodeRange);

View File

@@ -0,0 +1,31 @@
<html>
<body>
<form>
The buggy display : Select's size attribute is not specified :
<select multiple="multiple">
<optgroup label="Label">
<option label="a">a</option>
<option label="a">a</option>
<option label="a">a</option>
</optgroup>
</select>
<br>
<br>
<br>
What should be displayed : Select's size attribute is forced to 4 :
<select multiple="multiple" size="4">
<optgroup label="Label">
<option label="a">a</option>
<option label="a">a</option>
<option label="a">a</option>
</optgroup>
</select>
<br>
<br>
<br>
The width of the widget is also not perfect.
</form>
</body>
</html>

View File

@@ -0,0 +1,531 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Testcase for bug 300474</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:12px; padding:0; margin:0;
}
p { font-weight: bold; color:blue; margin-top:0; }
</style>
</head>
<body>
<p>unspecified size</p>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
</select>
<select multiple>
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple>
<option>o
<option>o
<option>o
</select>
<select multiple>
<option>o
<option>o
</select>
<select multiple>
<option>o
</select>
<select multiple>
</select>
<br>
<hr>
<br>
<p>size=0</p>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple size=0>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple size=0>
<option>o
<option>o
<option>o
</select>
<select multiple size=0>
<option>o
<option>o
</select>
<select multiple size=0>
<option>o
</select>
<select multiple size=0>
</select>
<br>
<hr>
<br>
<p>size=1</p>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple size=1>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple size=1>
<option>o
<option>o
<option>o
</select>
<select multiple size=1>
<option>o
<option>o
</select>
<select multiple size=1>
<option>o
</select>
<select multiple size=1>
</select>
<br>
<hr>
<br>
<p>size=4</p>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple size=4>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple size=4>
<option>o
<option>o
<option>o
</select>
<select multiple size=4>
<option>o
<option>o
</select>
<select multiple size=4>
<option>o
</select>
<select multiple size=4>
</select>
<br>
<hr>
<br>
<p>CSS height:300px</p>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
</select>
<select multiple style="height:300px">
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
<option>o
</select>
<select multiple style="height:300px">
<optgroup label="g"></optgroup>
<optgroup label="g"></optgroup>
</select>
<select multiple style="height:300px">
<option>o
<option>o
<option>o
</select>
<select multiple style="height:300px">
<option>o
<option>o
</select>
<select multiple style="height:300px">
<option>o
</select>
<select multiple style="height:300px">
</select>
</body>
</html>

View File

@@ -0,0 +1,40 @@
<div style="border: 1px solid blue; min-width: 200px;">
Div 1: min-width:200px
</div>
<br>
<div style="border: 1px solid blue; width: 200px;">
Div 2: max-width:200px max-width:200px max-width:200px max-width:200px
max-width:200px
</div>
<br>
<div style="border: 1px solid blue; max-width: 200px;">
Div 3: max-width:200px max-width:200px max-width:200px max-width:200px
max-width:200px
</div>
<br>
<br>
Div 4: min-width: 50px; max-width: 200px;
<div style="border: 1px solid blue; min-width: 50px; max-width: 200px;">
Div 4:
</div>
<br>
<br>
<form>
&lt;input type=text style="min-width:200px;"><br>
<input type=text style="min-width:200px;">
</form>

View File

@@ -0,0 +1,24 @@
<HTML>
<had>
<style>
input, select, label {
min-width: 100px;
max-width: 200px;
}
</style>
<BODY>
<form>
<div style="width:100px;background-color:#8888FF">100 pixels width</div>
<div style="width:200px;background-color:#88FF88">200 pixels width</div>
<div style="min-width: 100px;max-width: 200px;background-color:#FF8888">Div with min/max</div>
<input type=text><br>
<input type=text size=50><br>
<select>
<option>One
</select><br>
<select size=5>
<option>One
</select><br>
<label style="background-color:#88FF88">Label</label>
</BODY>
</HTML>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>min-width/max-width on label and inputs</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<style type="text/css">
label, input, textarea, select {
width: 100%;
min-width: 300px;
max-width: 500px;
display: block;
}
label {
border: 1px dashed red;
}
</style>
</head>
<body>
<p>All the lables (with the red and dashed border) and I should be at least 300px, at most 500px wide.</p>
<div style="width:300px;background:red;">This is fixed at 300px wide</div>
<div style="width:500px;background:green;">This is fixed at 500px wide</div>
<p>
<label for="a">Text:</label> <input id="a" type="text" />
</p>
<p>
<label for="b">Textarea:</label> <textarea id="b" rows="5" cols="2"></textarea>
</p>
<p>
<label for="c">Checkbox:</label> <input type="checkbox" id="c" />
</p>
<p>
<label for="d">Radio:</label> <input type="radio" id="d" />
</p>
<p>
<label for="e">Select:</label> <select id="e"><option>One</option><option>Two</option></select>
</p>
</body>
</html>

View File

@@ -0,0 +1,27 @@
<HTML>
<HEAD><TITLE>Test case for bug #7025</TITLE></HEAD>
<BODY ONLOAD="document.forms[0].elements[0].selectedIndex=4;document.forms[0].elements[1].selectedIndex=4">
<FORM>
<TABLE><TR><TD>
Multiple:
<SELECT SIZE="2" MULTIPLE>
<OPTION>1
<OPTION>2
<OPTION>3
<OPTION>4
<OPTION>5
<OPTION>6
</SELECT>
</TD><TD>
Not Multiple:
<SELECT SIZE="2">
<OPTION>1
<OPTION>2
<OPTION>3
<OPTION>4
<OPTION>5
<OPTION>6
</SELECT>
</TD></TR></TABLE>
</BODY>
</HTML>

View File

@@ -0,0 +1,78 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<HEAD>
<script>
function selectitem()
{
var node = document.getElementById("list1");
node.selectedIndex = 5;
node = document.getElementById("list2");
node.selectedIndex = 5;
}
</script>
</HEAD>
<BODY>
<table>
<tr>
<td>
<select id=list1>
<option>Lime0</option>
<option>Lime1</option>
<option>Lime2</option>
<option>Lime3</option>
<option>Lime4</option>
<option>Lime5</option>
<option>Lime6</option>
<option>Lime7</option>
<option>Lime0</option>
<option>Lime1</option>
<option>Lime2</option>
<option>Lime3</option>
<option>Lime4</option>
<option>Lime5</option>
<option>Lime6</option>
<option>Lime7</option>
<option>Lime0</option>
<option>Lime1</option>
<option>Lime2</option>
<option>Lime3</option>
<option>Lime4</option>
<option>Lime5</option>
<option>Lime6</option>
<option>Lime7</option>
<option>Lime0</option>
<option>Lime1</option>
<option>Lime2</option>
<option>Lime3</option>
<option>Lime4</option>
<option>Lime5</option>
<option>Lime6</option>
<option>Lime7</option>
<option selected>Strawberry</option>
</select>
</td>
<td>
<select size=3 id=list2>
<option>Lime0</option>
<option>Lime1</option>
<option>Lime2</option>
<option>Lime3</option>
<option>Lime4</option>
<option>Lime5</option>
<option>Lime6</option>
<option>Lime</option>
<option selected>Strawberry</option>
</select>
</td>
</tr>
</table>
<input type=button value="Select Item 5" onclick="selectitem()">
</body>
</HTML>

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* The Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Bienvenu <bienvenu@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIStringEnumerator.idl"
/*
* Keys are the internal representation of tags, and use a limited range of
* characters, basically the characters allowed in imap keywords, which are
* alphanumeric characters, but don't include spaces. Keys are stored on
* the imap server, in local mail messages, and in summary files.
*
* Tags are the user visible representation of keys, and are full unicode
* strings. Tags should allow any unicode character.
*
* This service will do the mapping between keys and tags. When a tag
* is added, we'll need to "compute" the corresponding key to use. This
* will probably entail replacing illegal ascii characters (' ', '/', etc)
* with '_' and then converting to imap mod utf7. We'll then need to make
* sure that no other keyword has the same value since that algorithm
* doesn't guarantee a unique mapping.
*
*/
[scriptable, uuid(ad04db53-cfcc-47eb-b409-b24b3a0b6130)]
interface nsIMsgTagService : nsISupports {
AString getTagForKey(in ACString key); // look up the tag for a key.
void setTagForKey(in ACString key, in AString tag); // this can be used to "rename" a tag
ACString getKeyForTag(in AString tag); // get the key representation of a given tag
void addTagForKey(in ACString key, in AString tag, in ACString color);
void addTag(in AString tag, in ACString color);
ACString getColorForKey(in ACString key);
void deleteTag(in AString tag);
// we need some way to enumerate all tags. Or return a list of all tags.
readonly attribute nsIStringEnumerator tagEnumerator;
readonly attribute nsIUTF8StringEnumerator keyEnumerator;
};

View File

@@ -0,0 +1,90 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the new tag dialog
*
* The Initial Developer of the Original Code is
* David Bienvenu.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Bienvenu <bienvenu@nventure.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var dialog;
function onLoad()
{
var arguments = window.arguments[0];
dialog = {};
dialog.OKButton = document.documentElement.getButton("accept");
dialog.nameField = document.getElementById("name");
dialog.nameField.focus();
// call this when OK is pressed
dialog.okCallback = arguments.okCallback;
moveToAlertPosition();
doEnabling();
}
function onOK()
{
var name = dialog.nameField.value;
var tagService = Components.classes["@mozilla.org/messenger/tagservice;1"].getService(Components.interfaces.nsIMsgTagService);
// do name validity check? Has to be non-empty, and not existing already
try
{
var key = tagService.getKeyForTag(name);
// above will throw an error if tag doesn't exist. So if it doesn't throw an error,
// the tag exists, so alert the user and return false.
}
catch (ex) {return dialog.okCallback(name, "")}
var messengerBundle = document.getElementById("bundle_messenger");
var alertText = messengerBundle.getString("tagExists");
window.alert(alertText);
return false;
}
function doEnabling()
{
if (dialog.nameField.value) {
if (dialog.OKButton.disabled)
dialog.OKButton.disabled = false;
} else {
if (!dialog.OKButton.disabled)
dialog.OKButton.disabled = true;
}
}

View File

@@ -0,0 +1,58 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.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/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Mozilla Mail Tag Support
-
- The Initial Developer of the Original Code is
- The Mozilla Corporation.
- Portions created by the Initial Developer are Copyright (C) 2006
- the Initial Developer. All Rights Reserved.
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://messenger/skin/dialogs.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://messenger/locale/newTagDialog.dtd">
<dialog xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&newTagDialog.title;"
onload="onLoad();"
ondialogaccept="return onOK();">
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
</stringbundleset>
<script type="application/x-javascript" src="chrome://messenger/content/newTagDialog.js"/>
<label value="&name.label;" accesskey="&name.accesskey;" control="name"/>
<textbox id="name" oninput="doEnabling();"/>
<separator/>
</dialog>

View File

@@ -0,0 +1,38 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.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/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is new tag dialog
-
- The Initial Developer of the Original Code is
- The Mozilla Corporation.
- Portions created by the Initial Developer are Copyright (C) 2006
- the Initial Developer. All Rights Reserved.
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!-- Labels -->
<!ENTITY newTagDialog.title "New Tag">
<!ENTITY name.label "Tag:">
<!ENTITY name.accesskey "T">

View File

@@ -0,0 +1,332 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Bienvenu <bienvenu@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "msgCore.h"
#include "nsMsgTagService.h"
#include "nsIPrefService.h"
#include "nsISupportsPrimitives.h"
#include "nsMsgI18N.h"
#include "nsIPrefLocalizedString.h"
#include "nsMsgDBView.h" // for labels migration
#include "nsStringEnumerator.h"
NS_IMPL_ISUPPORTS1(nsMsgTagService, nsIMsgTagService)
nsMsgTagService::nsMsgTagService()
{
m_prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
// need to figure out how to migrate the tags only once.
MigrateLabelsToTags();
}
nsMsgTagService::~nsMsgTagService()
{
/* destructor code */
}
/* wstring getTagForKey (in string key); */
NS_IMETHODIMP nsMsgTagService::GetTagForKey(const nsACString &key, nsAString &_retval)
{
nsCAutoString prefName("mailnews.tags.");
prefName.Append(key);
prefName.AppendLiteral(".tag");
return GetUnicharPref(prefName.get(), _retval);
}
/* void setTagForKey (in string key); */
NS_IMETHODIMP nsMsgTagService::SetTagForKey(const nsACString &key, const nsAString &tag )
{
nsCAutoString prefName("mailnews.tags.");
prefName.Append(key);
prefName.AppendLiteral(".tag");
return SetUnicharPref(prefName.get(), tag);
}
/* void getKeyForTag (in wstring tag); */
NS_IMETHODIMP nsMsgTagService::GetKeyForTag(const nsAString &aTag, nsACString &aKey)
{
PRUint32 count;
char **prefList;
nsresult rv = m_prefBranch->GetChildList("mailnews.tags.", &count, &prefList);
NS_ENSURE_SUCCESS(rv, rv);
// traverse the list, and look for a pref with the desired tag value.
for (PRUint32 i = count; i--; )
{
// The prefname we passed to GetChildList was of the form
// "mailnews.tags." and we are returned the descendants
// in the form of ""mailnews.tags.<key>.tag"
// But we only want the tags, so check that the string
// ends with tag.
if (StringEndsWith(nsDependentCString(prefList[i]), NS_LITERAL_CSTRING(".tag")))
{
nsAutoString curTag;
GetUnicharPref(prefList[i], curTag);
if (aTag.Equals(curTag))
{
aKey = Substring(nsDependentCString(prefList[i]), 14, strlen(prefList[i]) - 18);
break;
}
}
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, prefList);
return aKey.IsEmpty() ? NS_ERROR_FAILURE : NS_OK;
}
/* void addTagForKey (in string key, in wstring tag, in long color); */
NS_IMETHODIMP nsMsgTagService::AddTagForKey(const nsACString &key, const nsAString &tag, const nsACString &color)
{
nsCAutoString prefName("mailnews.tags.");
prefName.Append(key);
prefName.AppendLiteral(".tag");
SetUnicharPref(prefName.get(), tag);
prefName.Replace(prefName.Length() - 3, 3, NS_LITERAL_CSTRING("color"));
m_prefBranch->SetCharPref(prefName.get(), PromiseFlatCString(color).get());
return NS_OK;
}
/* void addTag (in wstring tag, in long color); */
NS_IMETHODIMP nsMsgTagService::AddTag(const nsAString &tag, const nsACString &color)
{
nsCAutoString prefName("mailnews.tags.");
// figure out key from tag. Apply transformation stripping out
// illegal characters like <SP> and then convert to imap mod utf7.
// Then, check if we have a tag with that key yet, and if so,
// make it unique by appending -1, -2, etc.
// Should we use an iterator?
nsAutoString transformedTag(tag);
transformedTag.ReplaceChar(" ()/{%*<>\\\"", '_');
nsCAutoString key;
CopyUTF16toMUTF7(transformedTag, key);
prefName.Append(key);
while (PR_TRUE)
{
nsAutoString tagValue;
GetUnicharPref(prefName.get(), tagValue);
if (tagValue.IsEmpty() || tagValue.Equals(tag))
return AddTagForKey(key, tag, color);
prefName.Append('A');
}
NS_ASSERTION(PR_FALSE, "can't get here");
return NS_ERROR_FAILURE;
}
/* long getColorForKey (in string key); */
NS_IMETHODIMP nsMsgTagService::GetColorForKey(const nsACString &key, nsACString &_retval)
{
nsCAutoString prefName("mailnews.tags.");
prefName.Append(key);
prefName.AppendLiteral(".color");
nsXPIDLCString color;
return m_prefBranch->GetCharPref(prefName.get(), getter_Copies(color));
_retval = color;
}
/* void deleteTag (in wstring tag); */
NS_IMETHODIMP nsMsgTagService::DeleteTag(const nsAString &tag)
{
// do we want to set a .deleted pref, or just set the tag
// property to "", or clear the pref(s)?
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute nsIStringEnumerator tagEnumerator; */
NS_IMETHODIMP nsMsgTagService::GetTagEnumerator(nsIStringEnumerator * *aTagEnumerator)
{
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 count;
char **prefList;
rv = prefBranch->GetChildList("mailnews.tags.", &count, &prefList);
NS_ENSURE_SUCCESS(rv, rv);
nsStringArray *stringArray = new nsStringArray(count); // or should it be count / 2?
if (!stringArray)
return NS_ERROR_OUT_OF_MEMORY;
// traverse the list, and truncate all the descendant strings to just
// one branch level below the root branch.
for (PRUint32 i = count; i--; )
{
// The prefname we passed to GetChildList was of the form
// "mailnews.tags." and we are returned the descendants
// in the form of ""mailnews.tags.<key>.tag"
// But we only want the tags, so check that the string
// ends with tag.
if (StringEndsWith(nsDependentCString(prefList[i]), NS_LITERAL_CSTRING(".tag")))
{
nsAutoString tag;
GetUnicharPref(prefList[i], tag);
stringArray->AppendString(tag);
}
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, prefList);
return NS_NewAdoptingStringEnumerator(aTagEnumerator, stringArray);;
}
NS_IMETHODIMP nsMsgTagService::GetKeyEnumerator(nsIUTF8StringEnumerator * *aKeyEnumerator)
{
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 count;
char **prefList;
rv = prefBranch->GetChildList("mailnews.tags.", &count, &prefList);
NS_ENSURE_SUCCESS(rv, rv);
nsCStringArray *stringArray = new nsCStringArray; // or should it be count / 2?
if (!stringArray)
return NS_ERROR_OUT_OF_MEMORY;
// traverse the list, and truncate all the descendant strings to just
// one branch level below the root branch.
for (PRUint32 i = count; i--; )
{
// The prefname we passed to GetChildList was of the form
// "mailnews.tags." and we are returned the descendants
// in the form of ""mailnews.tags.<key>.tag"
// But we only want the keys, so check that the string
// ends with tag.
if (StringEndsWith(nsDependentCString(prefList[i]), NS_LITERAL_CSTRING(".tag")))
{
nsCAutoString key;
nsDependentCString prefStr(prefList[i]);
prefStr.Mid(key, 14, strlen(prefList[i]) - 18);
stringArray->AppendCString(key);
}
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, prefList);
return NS_NewAdoptingUTF8StringEnumerator(aKeyEnumerator, stringArray);;
}
/* End of implementation class template. */
nsresult
nsMsgTagService::getPrefService()
{
if (m_prefBranch)
return NS_OK;
nsresult rv;
m_prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
m_prefBranch = nsnull;
return rv;
}
nsresult nsMsgTagService::SetUnicharPref(const char *prefName,
const nsAString &val)
{
nsresult rv = getPrefService();
NS_ENSURE_SUCCESS(rv, rv);
if (!val.IsEmpty())
{
nsCOMPtr<nsISupportsString> supportsString =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
if (supportsString)
{
supportsString->SetData(val);
rv = m_prefBranch->SetComplexValue(prefName,
NS_GET_IID(nsISupportsString),
supportsString);
}
}
else
{
m_prefBranch->ClearUserPref(prefName);
}
return rv;
}
nsresult nsMsgTagService::GetUnicharPref(const char *prefName,
nsAString &prefValue)
{
nsresult rv = getPrefService();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> supportsString =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
if (supportsString)
{
rv = m_prefBranch->GetComplexValue(prefName,
NS_GET_IID(nsISupportsString),
getter_AddRefs(supportsString));
if (supportsString)
rv = supportsString->GetData(prefValue);
else
prefValue.Truncate();
}
return rv;
}
nsresult nsMsgTagService::MigrateLabelsToTags()
{
nsCString prefString;
PRInt32 prefVersion = 0;
nsresult rv = m_prefBranch->GetIntPref("mailnews.tags.version", &prefVersion);
if (NS_SUCCEEDED(rv) && prefVersion == 1)
return rv;
nsCOMPtr<nsIPrefLocalizedString> pls;
nsXPIDLString ucsval;
nsCAutoString labelKey("$label1");
for(PRInt32 i = 0; i < PREF_LABELS_MAX; )
{
prefString.Assign(PREF_LABELS_DESCRIPTION);
prefString.AppendInt(i + 1);
rv = m_prefBranch->GetComplexValue(prefString.get(), NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
NS_ENSURE_SUCCESS(rv, rv);
pls->ToString(getter_Copies(ucsval));
prefString.Assign(PREF_LABELS_COLOR);
prefString.AppendInt(i + 1);
nsXPIDLCString csval;
NS_ENSURE_SUCCESS(rv, rv);
rv = m_prefBranch->GetCharPref(prefString.get(), getter_Copies(csval));
NS_ENSURE_SUCCESS(rv, rv);
rv = AddTagForKey(labelKey, ucsval, csval);
labelKey.SetCharAt(++i + '1', 6);
}
m_prefBranch->SetIntPref("mailnews.tags.version", 1);
return rv;
}

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Bienvenu <bienvenu@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMsgTagService_h__
#define nsMsgTagService_h__
#include "nsIMsgTagService.h"
#include "nsIPrefBranch.h"
class nsMsgTagEntry
{
public:
nsMsgTagEntry(const char *key, const PRUnichar *tag, PRUint32 color);
nsString m_tag;
nsCString m_key;
PRUint32 m_color;
};
class nsMsgTagService : public nsIMsgTagService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMSGTAGSERVICE
nsMsgTagService();
private:
~nsMsgTagService();
protected:
nsresult getPrefService() ;
nsresult SetUnicharPref(const char *prefName,
const nsAString &prefValue);
nsresult GetUnicharPref(const char *prefName,
nsAString &prefValue);
nsresult MigrateLabelsToTags();
nsCOMPtr<nsIPrefBranch> m_prefBranch;
};
#endif

View File

@@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Effective TLD Service
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pamela Greene <pamg.bugs@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(4b8cdd85-e186-46e5-9ec0-9488ae7f0b92)]
interface nsIEffectiveTLDService : nsISupports
{
/**
* getEffectiveTLDLength
*
* Finds the length of the effective TLD of a hostname. An effective TLD
* is the highest-level domain under which individual domains may be
* registered; it may therefore contain one or more dots. For example,
* the effective TLD for "www.bbc.co.uk" is "co.uk", because the .uk TLD
* does not allow the registration of domains at the second level ("bbc.uk"
* is forbidden). Similarly, the effective TLD of "developer.mozilla.com"
* is "com".
*
* The hostname will be normalized using nsIIDNService::normalize, which
* follows RFC 3454. getEffectiveTLDLength() will fail, generating an
* error, if the hostname contains characters that are invalid in URIs.
*
* @param aHostname The hostname to be analyzed, in UTF-8
*
* @returns the number of bytes that the longest identified effective TLD
* (TLD or TLD-like higher-level subdomain) occupies, not including
* the leading dot:
* bugzilla.mozilla.org -> org -> 3
* theregister.co.uk -> co.uk -> 5
* mysite.us -> us -> 2
*
* @throws NS_ERROR_UNEXPECTED
* or other error returned by nsIIDNService::normalize when
* aHostname is not UTF-8 or contains characters disallowed in URIs
*/
PRUint32 getEffectiveTLDLength(in AUTF8String aHostname);
};

View File

@@ -0,0 +1,584 @@
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Effective-TLD Service
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pamela Greene <pamg.bugs@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This service reads a file of rules describing TLD-like domain names. For a
// complete description of the expected file format and parsing rules, see
// http://wiki.mozilla.org/Gecko:Effective_TLD_Service
#include "nsEffectiveTLDService.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDataHashtable.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsFileStreams.h"
#include "nsIFile.h"
#include "nsIIDNService.h"
#include "nsNetUtil.h"
#include "nsString.h"
// The file name of the list of TLD-like names. A file with this name in the
// system "res" directory will always be used. In addition, if a file with
// the same name is present in the user's profile directory, its contents will
// also be used, as though those rules were appended to the system file.
#define EFF_TLD_FILENAME NS_LITERAL_CSTRING("effective_tld_names.dat")
// Define this as nonzero to eanble logging of the tree state after the file has
// been loaded.
#define EFF_TLD_SERVICE_DEBUG 0
/*
The list of subdomain rules is stored as a wide tree of SubdomainNodes,
primarily to facilitate multiple levels of wildcards. Each node represents
one level of a particular rule in the list, and stores meta-information about
the rule it represents as well as a list (hash) of all the subdomains beneath
it.
stopOK: If true, this node marks the end of a rule.
exception: If true, this node marks the end of an exception rule.
For example, if the effective-TLD list contains
foo.com
*.bar.com
!baz.bar.com
then the subdomain tree will look like this (conceptually; the actual order
of the nodes in the hashes is not guaranteed):
+--------------+
| com |
| exception: 0 | +--------------+
| stopOK: 0 | | foo |
| children ----|------> | exception: 0 |
+--------------+ | stopOK: 1 |
| children |
+--------------+
| bar |
| exception: 0 | +--------------+
| stopOK: 0 | | * |
| children ----|------> | exception: 0 |
+--------------+ | stopOK: 1 |
| children |
+--------------+
| baz |
| exception: 1 |
| stopOK: 1 |
| children |
+--------------+
*/
struct SubdomainNode;
typedef nsDataHashtable<nsCStringHashKey, SubdomainNode *> SubdomainNodeHash;
struct SubdomainNode {
PRBool exception;
PRBool stopOK;
SubdomainNodeHash children;
};
static void EmptyEffectiveTLDTree();
static nsresult LoadEffectiveTLDFiles();
static nsresult NormalizeHostname(nsCString &aHostname);
static PRInt32 FindEarlierDot(const nsACString &aHostname, PRInt32 aDotLoc);
static SubdomainNode *FindMatchingChildNode(SubdomainNode *parent,
const nsCSubstring &aSubname,
PRBool aCreateNewNode);
nsEffectiveTLDService* nsEffectiveTLDService::sInstance = nsnull;
static SubdomainNode sSubdomainTreeHead;
NS_IMPL_ISUPPORTS1(nsEffectiveTLDService, nsIEffectiveTLDService)
// ----------------------------------------------------------------------
#if defined(EFF_TLD_SERVICE_DEBUG) && EFF_TLD_SERVICE_DEBUG
// LOG_EFF_TLD_NODE
//
// If debugging is enabled, this function is called by LOG_EFF_TLD_TREE to
// recursively print the current state of the effective-TLD tree.
PR_STATIC_CALLBACK(PLDHashOperator)
LOG_EFF_TLD_NODE(const nsACString& aKey, SubdomainNode *aData, void *aLevel)
{
// Dump this node's information.
PRInt32 *level = (PRInt32 *) aLevel;
for (PRInt32 i = 0; i < *level; i++) printf("-");
if (aData->exception) printf("!");
if (aData->stopOK) printf("^");
printf("'%s'\n", PromiseFlatCString(aKey).get());
// Dump its children's information.
PRInt32 newlevel = (*level) + 1;
aData->children.EnumerateRead(LOG_EFF_TLD_NODE, &newlevel);
return PL_DHASH_NEXT;
}
#endif // EFF_TLD_SERVICE_DEBUG
// LOG_EFF_TLD_TREE
//
// If debugging is enabled, prints the current state of the effective-TLD tree.
void LOG_EFF_TLD_TREE(const char *msg = "",
SubdomainNode *head = &sSubdomainTreeHead)
{
#if defined(EFF_TLD_SERVICE_DEBUG) && EFF_TLD_SERVICE_DEBUG
if (msg && msg != "")
printf("%s\n", msg);
PRInt32 level = 0;
head->children.EnumerateRead(LOG_EFF_TLD_NODE, &level);
#endif // EFF_TLD_SERVICE_DEBUG
return;
}
// ----------------------------------------------------------------------
// nsEffectiveTLDService::Init
//
// Initializes the root subdomain node and loads the effective-TLD file.
// Returns NS_OK upon successful completion, propagated errors if any were
// encountered during the loading of the file and construction of the
// effective-TLD tree.
nsresult
nsEffectiveTLDService::Init()
{
sSubdomainTreeHead.exception = PR_FALSE;
sSubdomainTreeHead.stopOK = PR_FALSE;
nsresult rv = NS_OK;
if (!sSubdomainTreeHead.children.Init())
rv = NS_ERROR_OUT_OF_MEMORY;
if (NS_SUCCEEDED(rv))
rv = LoadEffectiveTLDFiles();
// In the event of an error, clear any partially constructed tree.
if (NS_FAILED(rv))
EmptyEffectiveTLDTree();
return rv;
}
// nsEffectiveTLDService::nsEffectiveTLDService
//
nsEffectiveTLDService::nsEffectiveTLDService()
{
NS_ASSERTION(!sInstance, "Multiple effective-TLD services being created");
sInstance = this;
}
// nsEffectiveTLDService::~nsEffectiveTLDService
//
nsEffectiveTLDService::~nsEffectiveTLDService()
{
NS_ASSERTION(sInstance == this, "Multiple effective-TLD services exist");
EmptyEffectiveTLDTree();
sInstance = nsnull;
}
// nsEffectiveTLDService::getEffectiveTLDLength
//
// The main external function: finds the length in bytes of the effective TLD
// for the given hostname. This will fail, generating an error, if the
// hostname is not UTF-8 or includes characters that are not valid in a URL.
NS_IMETHODIMP
nsEffectiveTLDService::GetEffectiveTLDLength(const nsACString &aHostname,
PRUint32 *effTLDLength)
{
// Calcluate a default length: either the level-0 TLD, or the whole string
// length if no dots are present.
PRInt32 nameLength = aHostname.Length();
PRInt32 defaultTLDLength;
PRInt32 dotLoc = FindEarlierDot(aHostname, nameLength - 1);
if (dotLoc < 0) {
defaultTLDLength = nameLength;
}
else {
defaultTLDLength = nameLength - dotLoc - 1;
}
*effTLDLength = NS_STATIC_CAST(PRUint32, defaultTLDLength);
// Create a mutable copy of the hostname and normalize it. This will fail
// if the hostname includes invalid characters.
nsCAutoString normHostname(aHostname);
nsresult rv = NormalizeHostname(normHostname);
if (NS_FAILED(rv))
return rv;
// Walk the domain tree looking for matches at each level.
SubdomainNode *node = &sSubdomainTreeHead;
dotLoc = nameLength;
while (dotLoc > 0) {
PRInt32 nextDotLoc = FindEarlierDot(normHostname, dotLoc - 1);
const nsCSubstring &subname = Substring(normHostname, nextDotLoc + 1,
dotLoc - nextDotLoc - 1);
SubdomainNode *child = FindMatchingChildNode(node, subname, false);
if (nsnull == child)
break;
if (child->exception) {
// Exception rules use one fewer levels than were matched.
*effTLDLength = NS_STATIC_CAST(PRUint32, nameLength - dotLoc - 1);
node = child;
break;
}
// For a normal match, save the location of the last stop, in case we find
// a non-stop match followed by a non-match further along.
if (child->stopOK)
*effTLDLength = NS_STATIC_CAST(PRUint32, nameLength - nextDotLoc - 1);
node = child;
dotLoc = nextDotLoc;
}
return NS_OK;
}
// ----------------------------------------------------------------------
PR_STATIC_CALLBACK(PLDHashOperator)
DeleteSubdomainNode(const nsACString& aKey, SubdomainNode *aData, void *aUser)
{
// Neither aData nor its children should ever be null in a properly
// constructed tree, but this function may also be called to clear a tree
// that encountered errors during initialization.
if (nsnull != aData && aData->children.IsInitialized()) {
// Delete this node's descendants.
aData->children.EnumerateRead(DeleteSubdomainNode, nsnull);
// Delete this node's hash of children.
aData->children.Clear();
}
return PL_DHASH_NEXT;
}
// EmptyEffectiveTLDTree
//
// Release the memory allocated by the static effective-TLD tree and reset the
// semaphore to indicate that the tree is not loaded.
void
EmptyEffectiveTLDTree()
{
if (sSubdomainTreeHead.children.IsInitialized()) {
sSubdomainTreeHead.children.EnumerateRead(DeleteSubdomainNode, nsnull);
sSubdomainTreeHead.children.Clear();
}
return;
}
// NormalizeHostname
//
// Normalizes characters of hostname. ASCII names are lower-cased, and names
// using other characters are normalized with nsIIDNService::Normalize, which
// follows RFC 3454.
nsresult NormalizeHostname(nsCString &aHostname)
{
nsresult rv = NS_OK;
if (IsASCII(aHostname)) {
ToLowerCase(aHostname);
}
else {
nsCOMPtr<nsIIDNService> idnServ = do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnServ)
rv = idnServ->Normalize(aHostname, aHostname);
}
return rv;
}
// ----------------------------------------------------------------------
// FillStringInformation
//
// Fills a start pointer and length for the given string.
void
FillStringInformation(const nsACString &aString, const char **start,
PRUint32 *length)
{
nsACString::const_iterator iter;
aString.BeginReading(iter);
*start = iter.get();
*length = iter.size_forward();
return;
}
// FindEarlierDot
//
// Finds the byte location of the next dot (.) at or earlier in the string than
// the given aDotLoc. Returns -1 if no more dots are found.
PRInt32
FindEarlierDot(const nsACString &aHostname, PRInt32 aDotLoc)
{
if (aDotLoc < 0)
return -1;
// Searching for '.' one byte at a time is fine since UTF-8 is a superset of
// 7-bit ASCII.
const char *start;
PRUint32 length;
FillStringInformation(aHostname, &start, &length);
PRInt32 endLoc = length - 1;
if (aDotLoc < endLoc)
endLoc = aDotLoc;
for (const char *where = start + endLoc; where >= start; --where) {
if (*where == '.')
return (where - start);
}
return -1;
}
// FindEndOfName
//
// Finds the byte loaction of the first space or tab in the string, or the
// length of the string (i.e., one past its end) if no spaces or tabs are found.
PRInt32
FindEndOfName(const nsACString &aHostname) {
// Searching for a space or tab one byte at a time is fine since UTF-8 is a
// superset of 7-bit ASCII.
const char *start;
PRUint32 length;
FillStringInformation(aHostname, &start, &length);
for (const char *where = start; where < start + length; ++where) {
if (*where == ' ' || *where == '\t')
return (where - start);
}
return length;
}
// FindMatchingChildNode
//
// Given a parent node and a candidate subname, searches the parent's children
// for a matching subdomain and returns a pointer to the matching node if one
// was found. If no exact match was found and aCreateNewNode is true, creates
// a new child node for the given subname and returns that, or nsnull if an
// error was encountered (typically because of memory allocation failure) while
// creating the new child.
//
// If no exact match was found and aCreateNewNode is false, looks for a
// wildcard node (*) instead. If no wildcard node is found either, returns
// nsnull.
//
// Typically, aCreateNewNode will be true when the subdomain tree is being
// built, and false when it is being searched to determine a hostname's
// effective TLD.
SubdomainNode *
FindMatchingChildNode(SubdomainNode *parent, const nsCSubstring &aSubname,
PRBool aCreateNewNode)
{
// Make a mutable copy of the name in case we need to strip ! from the start.
nsCAutoString name(aSubname);
PRBool exception = PR_FALSE;
// Is this node an exception?
if (name.Length() > 0 && name.First() == '!') {
exception = PR_TRUE;
name.Cut(0, 1);
}
// Look for an exact match.
SubdomainNode *result = nsnull;
SubdomainNode *match;
if (parent->children.Get(name, &match)) {
result = match;
}
// If the subname wasn't found, optionally create it.
else if (aCreateNewNode) {
SubdomainNode *node = new SubdomainNode;
if (node) {
node->exception = exception;
node->stopOK = PR_FALSE;
if (node->children.Init() && parent->children.Put(name, node))
result = node;
}
}
// Otherwise, if we're not making new nodes, look for a wildcard child.
else if (parent->children.Get(NS_LITERAL_CSTRING("*"), &match)) {
result = match;
}
return result;
}
// AddEffectiveTLDEntry
//
// Adds the given domain name rule to the effective-TLD tree.
//
// CAUTION: As a side effect, the domain name rule will be normalized: in the
// case of ASCII, it will be lower-cased; otherwise, it will be normalized as
// an IDN.
nsresult
AddEffectiveTLDEntry(nsCString &aDomainName) {
SubdomainNode *node = &sSubdomainTreeHead;
// Normalize the domain name.
nsresult rv = NormalizeHostname(aDomainName);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 dotLoc = FindEndOfName(aDomainName);
while (dotLoc > 0) {
PRInt32 nextDotLoc = FindEarlierDot(aDomainName, dotLoc - 1);
const nsCSubstring &subname = Substring(aDomainName, nextDotLoc + 1,
dotLoc - nextDotLoc - 1);
dotLoc = nextDotLoc;
node = FindMatchingChildNode(node, subname, true);
if (!node)
return NS_ERROR_OUT_OF_MEMORY;
}
// The last node in an entry is by definition a stop-OK node.
node->stopOK = true;
return NS_OK;
}
// LocateEffectiveTLDFile
//
// Locates the effective-TLD file. If aUseProfile is true, uses the file from
// the user's profile directory; otherwise uses the one from the system "res"
// directory. Places nsnull in foundFile if the desired file was not found.
nsresult
LocateEffectiveTLDFile(nsCOMPtr<nsIFile>& foundFile, PRBool aUseProfile)
{
foundFile = nsnull;
nsCOMPtr<nsIFile> effTLDFile = nsnull;
nsresult rv = NS_OK;
PRBool exists = PR_FALSE;
if (aUseProfile) {
// Look for the file in the user's profile directory.
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(effTLDFile));
// We allow a nonfatal error so that this component can be tested in an
// xpcshell with no profile present.
if (NS_FAILED(rv))
return rv;
}
else {
// Look for the file in the application "res" directory.
rv = NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR,
getter_AddRefs(effTLDFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = effTLDFile->AppendNative(NS_LITERAL_CSTRING("res"));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = effTLDFile->AppendNative(EFF_TLD_FILENAME);
NS_ENSURE_SUCCESS(rv, rv);
rv = effTLDFile->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (exists)
foundFile = effTLDFile;
return rv;
}
// LoadOneEffectiveTLDFile
//
// Loads the contents of the given effective-TLD file, building the tree as it
// goes.
nsresult
LoadOneEffectiveTLDFile(nsCOMPtr<nsIFile>& effTLDFile)
{
// Open the file as an input stream.
nsCOMPtr<nsIInputStream> fileStream;
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
effTLDFile,
0x01, // read-only mode
-1, // all permissions
nsIFileInputStream::CLOSE_ON_EOF);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILineInputStream> lineStream = do_QueryInterface(fileStream, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString lineData;
PRBool moreData = PR_TRUE;
NS_NAMED_LITERAL_CSTRING(commentMarker, "//");
while (moreData) {
rv = lineStream->ReadLine(lineData, &moreData);
if (NS_SUCCEEDED(rv)) {
if (! lineData.IsEmpty() &&
! StringBeginsWith(lineData, commentMarker)) {
rv = AddEffectiveTLDEntry(lineData);
}
}
else {
NS_WARNING("Error reading effective-TLD file; attempting to continue");
}
}
LOG_EFF_TLD_TREE("Effective-TLD tree:");
return rv;
}
// LoadEffectiveTLDFiles
//
// Loads the contents of the system and user effective-TLD files.
nsresult
LoadEffectiveTLDFiles()
{
nsCOMPtr<nsIFile> effTLDFile;
nsresult rv = LocateEffectiveTLDFile(effTLDFile, false);
// If we didn't find any system effective-TLD file, warn but keep trying. We
// can struggle along using the base TLDs.
if (NS_FAILED(rv) || nsnull == effTLDFile) {
NS_WARNING("No effective-TLD file found in system res directory");
}
else {
rv = LoadOneEffectiveTLDFile(effTLDFile);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = LocateEffectiveTLDFile(effTLDFile, true);
// Since the profile copy isn't strictly needed, ignore any errors trying to
// find or read it, in order to allow testing using xpcshell.
if (NS_FAILED(rv) || nsnull == effTLDFile)
return NS_OK;
return LoadOneEffectiveTLDFile(effTLDFile);
}

View File

@@ -0,0 +1,53 @@
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.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/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla TLD Service
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pamela Greene <pamg.bugs@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIEffectiveTLDService.h"
class nsEffectiveTLDService : public nsIEffectiveTLDService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIEFFECTIVETLDSERVICE
nsEffectiveTLDService();
nsresult Init();
private:
static nsEffectiveTLDService* sInstance;
~nsEffectiveTLDService();
};

View File

@@ -0,0 +1,66 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.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/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Firefox build scripts.
#
# The Initial Developer of the Original Code is
# the Mozilla Foundation <http://www.mozilla.org>.
#
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Robert Strong <rstrong@mozilla.com> - Initial perl scripts (install_sub.pl)
# Benjamin Smedberg <benjamin@smedbergs.us> - Makefile-izing
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
ifndef CONFIG_DIR
$(error CONFIG_DIR must be set before including makensis.mk)
endif
ifndef SFX_MODULE
$(error SFX_MODULE must be set before including makensis.mk)
endif
TOOLKIT_NSIS_FILES = \
common.nsh \
installer.nsi \
options.ini \
shortcuts.ini \
ShellLink.dll \
version.nsh \
$(NULL)
installer::
$(INSTALL) $(addprefix $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
$(INSTALL) $(topsrcdir)/toolkit/mozapps/installer/windows/wizard/setuprsc/setup.ico $(CONFIG_DIR)
$(INSTALL) $(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/installer/windows/commonLocale.nsh $(CONFIG_DIR)
cd $(CONFIG_DIR) && makensis.exe installer.nsi
$(INSTALL) $(CONFIG_DIR)/removed-files.log $(CONFIG_DIR)/setup.exe $(DEPTH)/installer-stage
cd $(DEPTH)/installer-stage && $(CYGWIN_WRAPPER) 7z a -t7z $(CONFIG_DIR)/app.7z -mx -m0=BCJ2 -m1=LZMA:d24 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3
$(CYGWIN_WRAPPER) upx --best -o $(CONFIG_DIR)/7zSD.sfx $(SFX_MODULE)
$(NSINSTALL) -D $(DIST)/install/sea
cat $(CONFIG_DIR)/7zSD.sfx $(CONFIG_DIR)/app.tag $(CONFIG_DIR)/app.7z > $(DIST)/install/sea/$(PKG_BASENAME).installer.exe
chmod 0755 $(DIST)/install/sea/$(PKG_BASENAME).installer.exe