Compare commits
1 Commits
Bugzilla_P
...
TREX_GFXWI
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc1b35ec92 |
24
mozilla/gfx/Makefile
Normal file
24
mozilla/gfx/Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ..
|
||||
|
||||
DIRS = src tests
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
BIN
mozilla/gfx/macbuild/gfx.mcp
Normal file
BIN
mozilla/gfx/macbuild/gfx.mcp
Normal file
Binary file not shown.
22
mozilla/gfx/makefile.win
Normal file
22
mozilla/gfx/makefile.win
Normal file
@@ -0,0 +1,22 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..
|
||||
|
||||
DIRS= src tests
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
41
mozilla/gfx/src/Makefile
Normal file
41
mozilla/gfx/src/Makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../..
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
LIBRARY_NAME = raptorgfx
|
||||
|
||||
MODULE=raptor
|
||||
|
||||
REQUIRES=util img xpcom raptor netlib
|
||||
|
||||
LCFLAGS=-D_IMPL_NS_GFX
|
||||
|
||||
CPPSRCS=nsColor.cpp nsColorNames.cpp nsColorNamesRGB.cpp nsFont.cpp \
|
||||
nsImageGroup.cpp nsImageManager.cpp nsImageNetContext.cpp \
|
||||
nsImageRenderer.cpp nsImageRequest.cpp nsImageSystemServices.cpp \
|
||||
nsImageURL.cpp nsRect.cpp nsTransform2D.cpp nsFontCache.cpp
|
||||
|
||||
EXPORTS=nsColor.h nsColorNames.h nsCoord.h nsFont.h nsRect.h nsPoint.h \
|
||||
nsSize.h nsMargin.h nsTransform2D.h nsIRenderingContext.h \
|
||||
nsIFontMetrics.h nsIImageManager.h nsIImageGroup.h nsIImageRequest.h \
|
||||
nsIImageObserver.h nsIDeviceContext.h nsIFontCache.h nsIImage.h \
|
||||
nsGfxCIID.h
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
79
mozilla/gfx/src/makefile.win
Normal file
79
mozilla/gfx/src/makefile.win
Normal file
@@ -0,0 +1,79 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DIRS = windows
|
||||
|
||||
LIBRARY_NAME=gmgfx
|
||||
MODULE=raptor
|
||||
REQUIRES=util img xpcom raptor netlib
|
||||
|
||||
DEFINES=-D_IMPL_NS_GFX -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPPSRCS=nsColor.cpp nsColorNames.cpp nsColorNamesRGB.cpp nsFont.cpp \
|
||||
nsImageGroup.cpp nsImageManager.cpp nsImageNetContext.cpp \
|
||||
nsImageRenderer.cpp nsImageRequest.cpp nsImageSystemServices.cpp \
|
||||
nsImageURL.cpp nsRect.cpp nsTransform2D.cpp nsFontCache.cpp
|
||||
|
||||
EXPORTS=nsColor.h nsColorNames.h nsCoord.h nsFont.h nsRect.h nsPoint.h \
|
||||
nsSize.h nsMargin.h nsTransform2D.h nsIRenderingContext.h \
|
||||
nsIFontMetrics.h nsIImageManager.h nsIImageGroup.h nsIImageRequest.h \
|
||||
nsIImageObserver.h nsIDeviceContext.h nsIFontCache.h nsIImage.h \
|
||||
nsGfxCIID.h
|
||||
|
||||
CPP_OBJS=.\$(OBJDIR)\nsColor.obj .\$(OBJDIR)\nsColorNames.obj \
|
||||
.\$(OBJDIR)\nsColorNamesRGB.obj .\$(OBJDIR)\nsFont.obj \
|
||||
.\$(OBJDIR)\nsImageGroup.obj .\$(OBJDIR)\nsImageManager.obj \
|
||||
.\$(OBJDIR)\nsImageNetContext.obj .\$(OBJDIR)\nsImageRenderer.obj \
|
||||
.\$(OBJDIR)\nsImageRequest.obj .\$(OBJDIR)\nsImageSystemServices.obj \
|
||||
.\$(OBJDIR)\nsImageURL.obj .\$(OBJDIR)\nsRect.obj \
|
||||
.\$(OBJDIR)\nsTransform2D.obj .\$(OBJDIR)\nsFontCache.obj
|
||||
|
||||
LINCS=-I$(PUBLIC)\util -I$(PUBLIC)\img \
|
||||
-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \
|
||||
-I$(PUBLIC)\netlib
|
||||
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
DLLNAME = raptorgfx
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
$(DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
# These are the libraries we need to link with to create the dll
|
||||
LLIBS= \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
$(DIST)\lib\raptorbase.lib \
|
||||
$(DIST)\lib\img3240.lib \
|
||||
$(DIST)\lib\util.lib \
|
||||
$(DIST)\lib\libplc21.lib \
|
||||
$(DIST)\lib\netlib.lib \
|
||||
$(LIBNSPR)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\$(DLLNAME).dll
|
||||
rm -f $(DIST)\lib\$(DLLNAME).lib
|
||||
111
mozilla/gfx/src/nsColor.cpp
Normal file
111
mozilla/gfx/src/nsColor.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "plstr.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsColorNames.h"
|
||||
|
||||
static int ComponentValue(const char* aColorSpec, int dpc)
|
||||
{
|
||||
int component = 0;
|
||||
while (--dpc >= 0) {
|
||||
char ch = *aColorSpec++;
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
component = component*16 + (ch - '0');
|
||||
} else {
|
||||
// "ch&7" handles lower and uppercase hex alphabetics
|
||||
component = component*16 + (ch & 7) + 9;
|
||||
}
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
// Note: This handles 9 digits of hex to be compatible with eric
|
||||
// bina's original code. However, it is pickyer with respect to what a
|
||||
// legal color is and will only return true for perfectly legal color
|
||||
// values.
|
||||
NS_GFX PRBool NS_HexToRGB(const char* aColorSpec, nscolor* aResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aColorSpec, "null ptr");
|
||||
if (nsnull == aColorSpec) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (aColorSpec[0] == '#') {
|
||||
aColorSpec++;
|
||||
}
|
||||
|
||||
int nameLen = PL_strlen(aColorSpec);
|
||||
if ((nameLen == 3) || (nameLen == 6) || (nameLen == 9)) {
|
||||
// Make sure the digits are legal
|
||||
for (int i = 0; i < nameLen; i++) {
|
||||
char ch = aColorSpec[i];
|
||||
if (((ch >= '0') && (ch <= '9')) ||
|
||||
((ch >= 'a') && (ch <= 'f')) ||
|
||||
((ch >= 'A') && (ch <= 'F'))) {
|
||||
// Legal character
|
||||
continue;
|
||||
}
|
||||
// Whoops. Illegal character.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Convert the ascii to binary
|
||||
int dpc = nameLen / 3;
|
||||
|
||||
// Translate components from hex to binary
|
||||
int r = ComponentValue(aColorSpec, dpc);
|
||||
int g = ComponentValue(aColorSpec + dpc, dpc);
|
||||
int b = ComponentValue(aColorSpec + dpc*2, dpc);
|
||||
if (dpc == 1) {
|
||||
// Scale single digit component to an 8 bit value. Replicate the
|
||||
// single digit to compute the new value.
|
||||
r = (r << 4) | r;
|
||||
g = (g << 4) | g;
|
||||
b = (b << 4) | b;
|
||||
} else if (dpc == 3) {
|
||||
// Drop off the low digit from 12 bit values.
|
||||
r = r >> 4;
|
||||
g = g >> 4;
|
||||
b = b >> 4;
|
||||
}
|
||||
NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
|
||||
NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
|
||||
NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
|
||||
if (nsnull != aResult) {
|
||||
*aResult = NS_RGB(r, g, b);
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Improperly formatted color value
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool NS_ColorNameToRGB(const char* aColorName, nscolor* aResult)
|
||||
{
|
||||
PRInt32 id = nsColorNames::LookupName(aColorName);
|
||||
if (id >= 0) {
|
||||
NS_ASSERTION(id < COLOR_MAX, "LookupName mess up");
|
||||
if (nsnull != aResult) {
|
||||
*aResult = nsColorNames::kColors[id];
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
52
mozilla/gfx/src/nsColor.h
Normal file
52
mozilla/gfx/src/nsColor.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsColor_h___
|
||||
#define nsColor_h___
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
// A color is a 32 bit unsigned integer with four components: R, G, B
|
||||
// and A.
|
||||
typedef PRUint32 nscolor;
|
||||
|
||||
// Make a color out of r,g,b values. This assumes that the r,g,b values are
|
||||
// properly constrained to 0-255. This also assumes that a is 255.
|
||||
#define NS_RGB(_r,_g,_b) \
|
||||
((nscolor) ((255 << 24) | ((_b)<<16) | ((_g)<<8) | (_r)))
|
||||
|
||||
// Make a color out of r,g,b,a values. This assumes that the r,g,b,a
|
||||
// values are properly constrained to 0-255.
|
||||
#define NS_RGBA(_r,_g,_b,_a) \
|
||||
((nscolor) (((_a) << 24) | ((_b)<<16) | ((_g)<<8) | (_r)))
|
||||
|
||||
// Extract color components from nscolor
|
||||
#define NS_GET_R(_rgba) ((PRUint8) ((_rgba) & 0xff))
|
||||
#define NS_GET_G(_rgba) ((PRUint8) (((_rgba) >> 8) & 0xff))
|
||||
#define NS_GET_B(_rgba) ((PRUint8) (((_rgba) >> 16) & 0xff))
|
||||
#define NS_GET_A(_rgba) ((PRUint8) (((_rgba) >> 24) & 0xff))
|
||||
|
||||
// Translate a hex string to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
extern NS_GFX PRBool NS_HexToRGB(const char* aBuf, nscolor* aResult);
|
||||
|
||||
// Translate a color name to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
extern NS_GFX PRBool NS_ColorNameToRGB(const char* aBuf, nscolor* aResult);
|
||||
|
||||
#endif /* nsColor_h___ */
|
||||
142
mozilla/gfx/src/nsColorNameIDs.h
Normal file
142
mozilla/gfx/src/nsColorNameIDs.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* Do not edit - generated by genhash.pl */
|
||||
#define COLOR_ALICEBLUE 0
|
||||
#define COLOR_ANTIQUEWHITE 1
|
||||
#define COLOR_AQUA 2
|
||||
#define COLOR_AQUAMARINE 3
|
||||
#define COLOR_AZURE 4
|
||||
#define COLOR_BEIGE 5
|
||||
#define COLOR_BISQUE 6
|
||||
#define COLOR_BLACK 7
|
||||
#define COLOR_BLANCHEDALMOND 8
|
||||
#define COLOR_BLUE 9
|
||||
#define COLOR_BLUEVIOLET 10
|
||||
#define COLOR_BROWN 11
|
||||
#define COLOR_BURLYWOOD 12
|
||||
#define COLOR_CADETBLUE 13
|
||||
#define COLOR_CHARTREUSE 14
|
||||
#define COLOR_CHOCOLATE 15
|
||||
#define COLOR_CORAL 16
|
||||
#define COLOR_CORNFLOWERBLUE 17
|
||||
#define COLOR_CORNSILK 18
|
||||
#define COLOR_CRIMSON 19
|
||||
#define COLOR_CYAN 20
|
||||
#define COLOR_DARKBLUE 21
|
||||
#define COLOR_DARKCYAN 22
|
||||
#define COLOR_DARKGOLDENROD 23
|
||||
#define COLOR_DARKGRAY 24
|
||||
#define COLOR_DARKGREEN 25
|
||||
#define COLOR_DARKKHAKI 26
|
||||
#define COLOR_DARKMAGENTA 27
|
||||
#define COLOR_DARKOLIVEGREEN 28
|
||||
#define COLOR_DARKORANGE 29
|
||||
#define COLOR_DARKORCHID 30
|
||||
#define COLOR_DARKRED 31
|
||||
#define COLOR_DARKSALMON 32
|
||||
#define COLOR_DARKSEAGREEN 33
|
||||
#define COLOR_DARKSLATEBLUE 34
|
||||
#define COLOR_DARKSLATEGRAY 35
|
||||
#define COLOR_DARKTURQUOISE 36
|
||||
#define COLOR_DARKVIOLET 37
|
||||
#define COLOR_DEEPPINK 38
|
||||
#define COLOR_DEEPSKYBLUE 39
|
||||
#define COLOR_DIMGRAY 40
|
||||
#define COLOR_DODGERBLUE 41
|
||||
#define COLOR_FIREBRICK 42
|
||||
#define COLOR_FLORALWHITE 43
|
||||
#define COLOR_FORESTGREEN 44
|
||||
#define COLOR_FUCHSIA 45
|
||||
#define COLOR_GAINSBORO 46
|
||||
#define COLOR_GHOSTWHITE 47
|
||||
#define COLOR_GOLD 48
|
||||
#define COLOR_GOLDENROD 49
|
||||
#define COLOR_GRAY 50
|
||||
#define COLOR_GREEN 51
|
||||
#define COLOR_GREENYELLOW 52
|
||||
#define COLOR_HONEYDEW 53
|
||||
#define COLOR_HOTPINK 54
|
||||
#define COLOR_INDIANRED 55
|
||||
#define COLOR_INDIGO 56
|
||||
#define COLOR_IVORY 57
|
||||
#define COLOR_KHAKI 58
|
||||
#define COLOR_LAVENDER 59
|
||||
#define COLOR_LAVENDERBLUSH 60
|
||||
#define COLOR_LAWNGREEN 61
|
||||
#define COLOR_LEMONCHIFFON 62
|
||||
#define COLOR_LIGHTBLUE 63
|
||||
#define COLOR_LIGHTCORAL 64
|
||||
#define COLOR_LIGHTCYAN 65
|
||||
#define COLOR_LIGHTGOLDENRODYELLOW 66
|
||||
#define COLOR_LIGHTGREEN 67
|
||||
#define COLOR_LIGHTGREY 68
|
||||
#define COLOR_LIGHTPINK 69
|
||||
#define COLOR_LIGHTSALMON 70
|
||||
#define COLOR_LIGHTSEAGREEN 71
|
||||
#define COLOR_LIGHTSKYBLUE 72
|
||||
#define COLOR_LIGHTSLATEGRAY 73
|
||||
#define COLOR_LIGHTSTEELBLUE 74
|
||||
#define COLOR_LIGHTYELLOW 75
|
||||
#define COLOR_LIME 76
|
||||
#define COLOR_LIMEGREEN 77
|
||||
#define COLOR_LINEN 78
|
||||
#define COLOR_MAGENTA 79
|
||||
#define COLOR_MAROON 80
|
||||
#define COLOR_MEDIUMAQUAMARINE 81
|
||||
#define COLOR_MEDIUMBLUE 82
|
||||
#define COLOR_MEDIUMORCHID 83
|
||||
#define COLOR_MEDIUMPURPLE 84
|
||||
#define COLOR_MEDIUMSEAGREEN 85
|
||||
#define COLOR_MEDIUMSLATEBLUE 86
|
||||
#define COLOR_MEDIUMSPRINGGREEN 87
|
||||
#define COLOR_MEDIUMTURQUOISE 88
|
||||
#define COLOR_MEDIUMVIOLETRED 89
|
||||
#define COLOR_MIDNIGHTBLUE 90
|
||||
#define COLOR_MINTCREAM 91
|
||||
#define COLOR_MISTYROSE 92
|
||||
#define COLOR_MOCCASIN 93
|
||||
#define COLOR_NAVAJOWHITE 94
|
||||
#define COLOR_NAVY 95
|
||||
#define COLOR_OLDLACE 96
|
||||
#define COLOR_OLIVE 97
|
||||
#define COLOR_OLIVEDRAB 98
|
||||
#define COLOR_ORANGE 99
|
||||
#define COLOR_ORANGERED 100
|
||||
#define COLOR_ORCHID 101
|
||||
#define COLOR_PALEGOLDENROD 102
|
||||
#define COLOR_PALEGREEN 103
|
||||
#define COLOR_PALETURQUOISE 104
|
||||
#define COLOR_PALEVIOLETRED 105
|
||||
#define COLOR_PAPAYAWHIP 106
|
||||
#define COLOR_PEACHPUFF 107
|
||||
#define COLOR_PERU 108
|
||||
#define COLOR_PINK 109
|
||||
#define COLOR_PLUM 110
|
||||
#define COLOR_POWDERBLUE 111
|
||||
#define COLOR_PURPLE 112
|
||||
#define COLOR_RED 113
|
||||
#define COLOR_ROSYBROWN 114
|
||||
#define COLOR_ROYALBLUE 115
|
||||
#define COLOR_SADDLEBROWN 116
|
||||
#define COLOR_SALMON 117
|
||||
#define COLOR_SANDYBROWN 118
|
||||
#define COLOR_SEAGREEN 119
|
||||
#define COLOR_SEASHELL 120
|
||||
#define COLOR_SIENNA 121
|
||||
#define COLOR_SILVER 122
|
||||
#define COLOR_SKYBLUE 123
|
||||
#define COLOR_SLATEBLUE 124
|
||||
#define COLOR_SLATEGRAY 125
|
||||
#define COLOR_SNOW 126
|
||||
#define COLOR_SPRINGGREEN 127
|
||||
#define COLOR_STEELBLUE 128
|
||||
#define COLOR_TAN 129
|
||||
#define COLOR_TEAL 130
|
||||
#define COLOR_THISTLE 131
|
||||
#define COLOR_TOMATO 132
|
||||
#define COLOR_TURQUOISE 133
|
||||
#define COLOR_VIOLET 134
|
||||
#define COLOR_WHEAT 135
|
||||
#define COLOR_WHITE 136
|
||||
#define COLOR_WHITESMOKE 137
|
||||
#define COLOR_YELLOW 138
|
||||
#define COLOR_YELLOWGREEN 139
|
||||
#define COLOR_MAX 140
|
||||
566
mozilla/gfx/src/nsColorNames.cpp
Normal file
566
mozilla/gfx/src/nsColorNames.cpp
Normal file
@@ -0,0 +1,566 @@
|
||||
|
||||
/*
|
||||
** This is a generated file, do not edit it. This file is created by
|
||||
** genhash.pl
|
||||
*/
|
||||
|
||||
#include "plstr.h"
|
||||
#include "nsColorNames.h"
|
||||
#define TOTAL_KEYWORDS 140
|
||||
#define MIN_WORD_LENGTH 3
|
||||
#define MAX_WORD_LENGTH 20
|
||||
#define MIN_HASH_VALUE 5
|
||||
#define MAX_HASH_VALUE 573
|
||||
/* maximum key range = 569, duplicates = 0 */
|
||||
|
||||
|
||||
struct StaticNameTable {
|
||||
char* tag;
|
||||
PRInt32 id;
|
||||
};
|
||||
|
||||
static const unsigned char kLowerLookup[256] = {
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
||||
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
|
||||
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
|
||||
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
|
||||
64,
|
||||
97,98,99,100,101,102,103,104,105,106,107,108,109,
|
||||
110,111,112,113,114,115,116,117,118,119,120,121,122,
|
||||
|
||||
91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
|
||||
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
#define MYLOWER(x) kLowerLookup[((x) & 0x7f)]
|
||||
|
||||
/**
|
||||
* Map a name to an ID or -1
|
||||
*/
|
||||
PRInt32 nsColorNames::LookupName(const char* str)
|
||||
{
|
||||
static unsigned short asso_values[] =
|
||||
{
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 574, 574, 574,
|
||||
574, 574, 574, 574, 574, 574, 574, 0, 200, 245,
|
||||
30, 0, 105, 90, 0, 10, 0, 80, 0, 0,
|
||||
0, 0, 140, 30, 20, 5, 25, 10, 10, 70,
|
||||
574, 203, 5, 574, 574, 574, 574, 574,
|
||||
};
|
||||
static unsigned char lengthtable[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 5, 6, 0, 8,
|
||||
4, 5, 0, 0, 0, 0, 0, 6, 0, 8, 0, 0, 0, 0,
|
||||
3, 4, 15, 0, 7, 8, 4, 0, 16, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 10, 0, 0, 13, 14, 0, 11, 17, 3, 0, 0,
|
||||
6, 7, 8, 0, 10, 6, 0, 0, 9, 15, 0, 12, 0, 0,
|
||||
0, 0, 0, 0, 14, 5, 6, 12, 0, 4, 15, 0, 0, 0,
|
||||
0, 10, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 6, 0,
|
||||
0, 9, 0, 0, 7, 0, 0, 5, 6, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 5, 6, 7, 13, 9, 0, 0, 0, 0, 4, 5,
|
||||
0, 0, 0, 9, 0, 11, 0, 0, 0, 0, 0, 7, 0, 9,
|
||||
0, 0, 0, 13, 4, 0, 0, 0, 0, 9, 10, 0, 0, 0,
|
||||
4, 10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 0, 0,
|
||||
12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11, 0, 0, 9, 0, 0, 0, 0, 4, 5, 0, 4, 0, 9,
|
||||
0, 0, 0, 0, 9, 0, 11, 0, 0, 0, 10, 0, 0, 13,
|
||||
0, 5, 6, 0, 13, 9, 10, 0, 0, 0, 4, 0, 11, 0,
|
||||
0, 9, 0, 0, 9, 0, 9, 20, 0, 0, 8, 9, 5, 0,
|
||||
7, 13, 9, 10, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 8, 0, 10, 13, 0, 0, 0, 0, 0, 7, 0, 14,
|
||||
0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 10, 0, 0, 13,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 12,
|
||||
0, 0, 0, 8, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 0, 0, 0,
|
||||
11, 0, 0, 0, 0, 0, 12, 0, 0, 10, 0, 0, 8, 6,
|
||||
0, 8, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 12, 0,
|
||||
0, 5, 0, 0, 0, 0, 0, 0, 14, 0, 11, 0, 0, 0,
|
||||
0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 9, 0, 0,
|
||||
0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
|
||||
0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14,
|
||||
0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 10, 9, 0, 0, 0, 0, 9, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
|
||||
9, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 10,
|
||||
|
||||
};
|
||||
static struct StaticNameTable wordlist[] =
|
||||
{
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"olive", 97},
|
||||
{"maroon", 80},
|
||||
{"",}, {"",}, {"",},
|
||||
{"azure", 4},
|
||||
{"salmon", 117},
|
||||
{"",},
|
||||
{"seashell", 120},
|
||||
{"lime", 76},
|
||||
{"linen", 78},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"sienna", 121},
|
||||
{"",},
|
||||
{"moccasin", 93},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"tan", 129},
|
||||
{"teal", 130},
|
||||
{"mediumslateblue", 86},
|
||||
{"",},
|
||||
{"magenta", 79},
|
||||
{"seagreen", 119},
|
||||
{"aqua", 2},
|
||||
{"",},
|
||||
{"mediumaquamarine", 81},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"darksalmon", 32},
|
||||
{"",}, {"",},
|
||||
{"darkslateblue", 34},
|
||||
{"mediumseagreen", 85},
|
||||
{"",},
|
||||
{"lightsalmon", 70},
|
||||
{"mediumspringgreen", 87},
|
||||
{"red", 113},
|
||||
{"",}, {"",},
|
||||
{"tomato", 132},
|
||||
{"thistle", 131},
|
||||
{"lavender", 59},
|
||||
{"",},
|
||||
{"aquamarine", 3},
|
||||
{"silver", 122},
|
||||
{"",}, {"",},
|
||||
{"turquoise", 133},
|
||||
{"mediumvioletred", 89},
|
||||
{"",},
|
||||
{"darkseagreen", 33},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"darkolivegreen", 28},
|
||||
{"white", 136},
|
||||
{"violet", 134},
|
||||
{"antiquewhite", 1},
|
||||
{"",},
|
||||
{"snow", 126},
|
||||
{"mediumturquoise", 88},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"darkviolet", 37},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"navajowhite", 94},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"orchid", 101},
|
||||
{"",}, {"",},
|
||||
{"indianred", 55},
|
||||
{"",}, {"",},
|
||||
{"skyblue", 123},
|
||||
{"",}, {"",},
|
||||
{"khaki", 58},
|
||||
{"indigo", 56},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"green", 51},
|
||||
{"orange", 99},
|
||||
{"darkred", 31},
|
||||
{"darkturquoise", 36},
|
||||
{"lawngreen", 61},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"gold", 48},
|
||||
{"wheat", 135},
|
||||
{"",}, {"",}, {"",},
|
||||
{"limegreen", 77},
|
||||
{"",},
|
||||
{"darkmagenta", 27},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"fuchsia", 45},
|
||||
{"",},
|
||||
{"darkkhaki", 26},
|
||||
{"",}, {"",}, {"",},
|
||||
{"lightseagreen", 71},
|
||||
{"plum", 110},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"darkgreen", 25},
|
||||
{"darkorange", 29},
|
||||
{"",}, {"",}, {"",},
|
||||
{"peru", 108},
|
||||
{"lightgreen", 67},
|
||||
{"purple", 112},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"whitesmoke", 137},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",},
|
||||
{"hotpink", 54},
|
||||
{"",},
|
||||
{"goldenrod", 49},
|
||||
{"",}, {"",},
|
||||
{"mediumpurple", 84},
|
||||
{"darkgoldenrod", 23},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",},
|
||||
{"floralwhite", 43},
|
||||
{"",}, {"",},
|
||||
{"orangered", 100},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"blue", 9},
|
||||
{"beige", 5},
|
||||
{"",},
|
||||
{"navy", 95},
|
||||
{"",},
|
||||
{"aliceblue", 0},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"slateblue", 124},
|
||||
{"",},
|
||||
{"saddlebrown", 116},
|
||||
{"",}, {"",}, {"",},
|
||||
{"ghostwhite", 47},
|
||||
{"",}, {"",},
|
||||
{"palevioletred", 105},
|
||||
{"",},
|
||||
{"brown", 11},
|
||||
{"bisque", 6},
|
||||
{"",},
|
||||
{"paleturquoise", 104},
|
||||
{"royalblue", 115},
|
||||
{"mediumblue", 82},
|
||||
{"",}, {"",}, {"",},
|
||||
{"pink", 109},
|
||||
{"",},
|
||||
{"forestgreen", 44},
|
||||
{"",}, {"",},
|
||||
{"steelblue", 128},
|
||||
{"",}, {"",},
|
||||
{"mistyrose", 92},
|
||||
{"",},
|
||||
{"lightblue", 63},
|
||||
{"lightgoldenrodyellow", 66},
|
||||
{"",}, {"",},
|
||||
{"darkblue", 21},
|
||||
{"rosybrown", 114},
|
||||
{"coral", 16},
|
||||
{"",},
|
||||
{"oldlace", 96},
|
||||
{"lavenderblush", 60},
|
||||
{"chocolate", 15},
|
||||
{"blueviolet", 10},
|
||||
{"",}, {"",}, {"",},
|
||||
{"palegreen", 103},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"deeppink", 38},
|
||||
{"",},
|
||||
{"dodgerblue", 41},
|
||||
{"darkslategray", 35},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"crimson", 19},
|
||||
{"",},
|
||||
{"lightsteelblue", 74},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"mintcream", 91},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"lightcoral", 64},
|
||||
{"",}, {"",},
|
||||
{"palegoldenrod", 102},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",},
|
||||
{"gainsboro", 46},
|
||||
{"chartreuse", 14},
|
||||
{"",},
|
||||
{"mediumorchid", 83},
|
||||
{"",}, {"",}, {"",},
|
||||
{"honeydew", 53},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"gray", 50},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",},
|
||||
{"deepskyblue", 39},
|
||||
{"",}, {"",},
|
||||
{"midnightblue", 90},
|
||||
{"",}, {"",}, {"",},
|
||||
{"springgreen", 127},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"lightskyblue", 72},
|
||||
{"",}, {"",},
|
||||
{"darkorchid", 30},
|
||||
{"",}, {"",},
|
||||
{"cornsilk", 18},
|
||||
{"yellow", 138},
|
||||
{"",},
|
||||
{"darkgray", 24},
|
||||
{"",}, {"",},
|
||||
{"lightpink", 69},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"lemonchiffon", 62},
|
||||
{"",}, {"",},
|
||||
{"black", 7},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"lightslategray", 73},
|
||||
{"",},
|
||||
{"yellowgreen", 139},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"powderblue", 111},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"lightyellow", 75},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"ivory", 57},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",},
|
||||
{"cyan", 20},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"olivedrab", 98},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"greenyellow", 52},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"dimgray", 40},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"cadetblue", 13},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"darkcyan", 22},
|
||||
{"",}, {"",},
|
||||
{"blanchedalmond", 8},
|
||||
{"",}, {"",},
|
||||
{"lightcyan", 65},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"sandybrown", 118},
|
||||
{"peachpuff", 107},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"firebrick", 42},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"slategray", 125},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",},
|
||||
{"burlywood", 12},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"lightgrey", 68},
|
||||
{"",}, {"",}, {"",},
|
||||
{"cornflowerblue", 17},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"papayawhip", 106},
|
||||
};
|
||||
|
||||
if (str != NULL) {
|
||||
int len = PL_strlen(str);
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) {
|
||||
register int hval = len;
|
||||
|
||||
switch (hval)
|
||||
{
|
||||
default:
|
||||
case 11:
|
||||
hval += asso_values[MYLOWER(str[10])];
|
||||
case 10:
|
||||
case 9:
|
||||
hval += asso_values[MYLOWER(str[8])];
|
||||
case 8:
|
||||
case 7:
|
||||
hval += asso_values[MYLOWER(str[6])];
|
||||
case 6:
|
||||
hval += asso_values[MYLOWER(str[5])];
|
||||
case 5:
|
||||
hval += asso_values[MYLOWER(str[4])];
|
||||
case 4:
|
||||
case 3:
|
||||
case 2:
|
||||
hval += asso_values[MYLOWER(str[1])];
|
||||
case 1:
|
||||
hval += asso_values[MYLOWER(str[0])];
|
||||
break;
|
||||
}
|
||||
hval += asso_values[MYLOWER(str[len - 1])];
|
||||
if (hval <= MAX_HASH_VALUE && hval >= MIN_HASH_VALUE) {
|
||||
if (len == lengthtable[hval]) {
|
||||
register const char *tag = wordlist[hval].tag;
|
||||
|
||||
/*
|
||||
** While not at the end of the string, if they ever differ
|
||||
** they are not equal. We know "tag" is already lower case.
|
||||
*/
|
||||
while ((*tag != '\0')&&(*str != '\0')) {
|
||||
if (*tag != (char) MYLOWER(*str)) {
|
||||
return -1;
|
||||
}
|
||||
tag++;
|
||||
str++;
|
||||
}
|
||||
|
||||
/*
|
||||
** One of the strings has ended, if they are both ended, then they
|
||||
** are equal, otherwise not.
|
||||
*/
|
||||
if ((*tag == '\0')&&(*str == '\0')) {
|
||||
return wordlist[hval].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const nsColorNames::NameTableEntry nsColorNames::kNameTable[] = {
|
||||
{ "aliceblue", 0 },
|
||||
{ "antiquewhite", 1 },
|
||||
{ "aqua", 2 },
|
||||
{ "aquamarine", 3 },
|
||||
{ "azure", 4 },
|
||||
{ "beige", 5 },
|
||||
{ "bisque", 6 },
|
||||
{ "black", 7 },
|
||||
{ "blanchedalmond", 8 },
|
||||
{ "blue", 9 },
|
||||
{ "blueviolet", 10 },
|
||||
{ "brown", 11 },
|
||||
{ "burlywood", 12 },
|
||||
{ "cadetblue", 13 },
|
||||
{ "chartreuse", 14 },
|
||||
{ "chocolate", 15 },
|
||||
{ "coral", 16 },
|
||||
{ "cornflowerblue", 17 },
|
||||
{ "cornsilk", 18 },
|
||||
{ "crimson", 19 },
|
||||
{ "cyan", 20 },
|
||||
{ "darkblue", 21 },
|
||||
{ "darkcyan", 22 },
|
||||
{ "darkgoldenrod", 23 },
|
||||
{ "darkgray", 24 },
|
||||
{ "darkgreen", 25 },
|
||||
{ "darkkhaki", 26 },
|
||||
{ "darkmagenta", 27 },
|
||||
{ "darkolivegreen", 28 },
|
||||
{ "darkorange", 29 },
|
||||
{ "darkorchid", 30 },
|
||||
{ "darkred", 31 },
|
||||
{ "darksalmon", 32 },
|
||||
{ "darkseagreen", 33 },
|
||||
{ "darkslateblue", 34 },
|
||||
{ "darkslategray", 35 },
|
||||
{ "darkturquoise", 36 },
|
||||
{ "darkviolet", 37 },
|
||||
{ "deeppink", 38 },
|
||||
{ "deepskyblue", 39 },
|
||||
{ "dimgray", 40 },
|
||||
{ "dodgerblue", 41 },
|
||||
{ "firebrick", 42 },
|
||||
{ "floralwhite", 43 },
|
||||
{ "forestgreen", 44 },
|
||||
{ "fuchsia", 45 },
|
||||
{ "gainsboro", 46 },
|
||||
{ "ghostwhite", 47 },
|
||||
{ "gold", 48 },
|
||||
{ "goldenrod", 49 },
|
||||
{ "gray", 50 },
|
||||
{ "green", 51 },
|
||||
{ "greenyellow", 52 },
|
||||
{ "honeydew", 53 },
|
||||
{ "hotpink", 54 },
|
||||
{ "indianred", 55 },
|
||||
{ "indigo", 56 },
|
||||
{ "ivory", 57 },
|
||||
{ "khaki", 58 },
|
||||
{ "lavender", 59 },
|
||||
{ "lavenderblush", 60 },
|
||||
{ "lawngreen", 61 },
|
||||
{ "lemonchiffon", 62 },
|
||||
{ "lightblue", 63 },
|
||||
{ "lightcoral", 64 },
|
||||
{ "lightcyan", 65 },
|
||||
{ "lightgoldenrodyellow", 66 },
|
||||
{ "lightgreen", 67 },
|
||||
{ "lightgrey", 68 },
|
||||
{ "lightpink", 69 },
|
||||
{ "lightsalmon", 70 },
|
||||
{ "lightseagreen", 71 },
|
||||
{ "lightskyblue", 72 },
|
||||
{ "lightslategray", 73 },
|
||||
{ "lightsteelblue", 74 },
|
||||
{ "lightyellow", 75 },
|
||||
{ "lime", 76 },
|
||||
{ "limegreen", 77 },
|
||||
{ "linen", 78 },
|
||||
{ "magenta", 79 },
|
||||
{ "maroon", 80 },
|
||||
{ "mediumaquamarine", 81 },
|
||||
{ "mediumblue", 82 },
|
||||
{ "mediumorchid", 83 },
|
||||
{ "mediumpurple", 84 },
|
||||
{ "mediumseagreen", 85 },
|
||||
{ "mediumslateblue", 86 },
|
||||
{ "mediumspringgreen", 87 },
|
||||
{ "mediumturquoise", 88 },
|
||||
{ "mediumvioletred", 89 },
|
||||
{ "midnightblue", 90 },
|
||||
{ "mintcream", 91 },
|
||||
{ "mistyrose", 92 },
|
||||
{ "moccasin", 93 },
|
||||
{ "navajowhite", 94 },
|
||||
{ "navy", 95 },
|
||||
{ "oldlace", 96 },
|
||||
{ "olive", 97 },
|
||||
{ "olivedrab", 98 },
|
||||
{ "orange", 99 },
|
||||
{ "orangered", 100 },
|
||||
{ "orchid", 101 },
|
||||
{ "palegoldenrod", 102 },
|
||||
{ "palegreen", 103 },
|
||||
{ "paleturquoise", 104 },
|
||||
{ "palevioletred", 105 },
|
||||
{ "papayawhip", 106 },
|
||||
{ "peachpuff", 107 },
|
||||
{ "peru", 108 },
|
||||
{ "pink", 109 },
|
||||
{ "plum", 110 },
|
||||
{ "powderblue", 111 },
|
||||
{ "purple", 112 },
|
||||
{ "red", 113 },
|
||||
{ "rosybrown", 114 },
|
||||
{ "royalblue", 115 },
|
||||
{ "saddlebrown", 116 },
|
||||
{ "salmon", 117 },
|
||||
{ "sandybrown", 118 },
|
||||
{ "seagreen", 119 },
|
||||
{ "seashell", 120 },
|
||||
{ "sienna", 121 },
|
||||
{ "silver", 122 },
|
||||
{ "skyblue", 123 },
|
||||
{ "slateblue", 124 },
|
||||
{ "slategray", 125 },
|
||||
{ "snow", 126 },
|
||||
{ "springgreen", 127 },
|
||||
{ "steelblue", 128 },
|
||||
{ "tan", 129 },
|
||||
{ "teal", 130 },
|
||||
{ "thistle", 131 },
|
||||
{ "tomato", 132 },
|
||||
{ "turquoise", 133 },
|
||||
{ "violet", 134 },
|
||||
{ "wheat", 135 },
|
||||
{ "white", 136 },
|
||||
{ "whitesmoke", 137 },
|
||||
{ "yellow", 138 },
|
||||
{ "yellowgreen", 139 },
|
||||
};
|
||||
44
mozilla/gfx/src/nsColorNames.h
Normal file
44
mozilla/gfx/src/nsColorNames.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsColorNames_h___
|
||||
#define nsColorNames_h___
|
||||
|
||||
#include "nsColor.h"
|
||||
#include "nsColorNameIDs.h"
|
||||
|
||||
class NS_GFX nsColorNames {
|
||||
public:
|
||||
// Given a null terminated string of 7 bit characters, return the
|
||||
// tag id (see nsHTMLTagIDs.h) for the tag or -1 if the tag is not
|
||||
// known. The lookup function uses a perfect hash.
|
||||
static PRInt32 LookupName(const char* str);
|
||||
|
||||
// Color id to rgb value table
|
||||
static nscolor kColors[];
|
||||
|
||||
struct NameTableEntry {
|
||||
const char* name;
|
||||
PRInt32 id;
|
||||
};
|
||||
|
||||
// A table whose index is the id (from LookupName)
|
||||
static const NameTableEntry kNameTable[];
|
||||
};
|
||||
|
||||
#endif /* nsColorNames_h___ */
|
||||
144
mozilla/gfx/src/nsColorNamesRGB.cpp
Normal file
144
mozilla/gfx/src/nsColorNamesRGB.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/* Do not edit - generated by tools/Makefile */
|
||||
#include "nsColorNames.h"
|
||||
nscolor nsColorNames::kColors[COLOR_MAX] = {
|
||||
NS_RGB(240, 248, 255),
|
||||
NS_RGB(250, 235, 215),
|
||||
NS_RGB( 0, 255, 255),
|
||||
NS_RGB(127, 255, 212),
|
||||
NS_RGB(240, 255, 255),
|
||||
NS_RGB(245, 245, 220),
|
||||
NS_RGB(255, 228, 196),
|
||||
NS_RGB( 0, 0, 0),
|
||||
NS_RGB(255, 235, 205),
|
||||
NS_RGB( 0, 0, 255),
|
||||
NS_RGB(138, 43, 226),
|
||||
NS_RGB(165, 42, 42),
|
||||
NS_RGB(222, 184, 135),
|
||||
NS_RGB( 95, 158, 160),
|
||||
NS_RGB(127, 255, 0),
|
||||
NS_RGB(210, 105, 30),
|
||||
NS_RGB(255, 127, 80),
|
||||
NS_RGB(100, 149, 237),
|
||||
NS_RGB(255, 248, 220),
|
||||
NS_RGB(220, 20, 60),
|
||||
NS_RGB( 0, 255, 255),
|
||||
NS_RGB( 0, 0, 139),
|
||||
NS_RGB( 0, 139, 139),
|
||||
NS_RGB(184, 134, 11),
|
||||
NS_RGB(169, 169, 169),
|
||||
NS_RGB( 0, 100, 0),
|
||||
NS_RGB(189, 183, 107),
|
||||
NS_RGB(139, 0, 139),
|
||||
NS_RGB( 85, 107, 47),
|
||||
NS_RGB(255, 140, 0),
|
||||
NS_RGB(153, 50, 204),
|
||||
NS_RGB(139, 0, 0),
|
||||
NS_RGB(233, 150, 122),
|
||||
NS_RGB(143, 188, 143),
|
||||
NS_RGB( 72, 61, 139),
|
||||
NS_RGB( 47, 79, 79),
|
||||
NS_RGB( 0, 206, 209),
|
||||
NS_RGB(148, 0, 211),
|
||||
NS_RGB(255, 20, 147),
|
||||
NS_RGB( 0, 191, 255),
|
||||
NS_RGB(105, 105, 105),
|
||||
NS_RGB( 30, 144, 255),
|
||||
NS_RGB(178, 34, 34),
|
||||
NS_RGB(255, 250, 240),
|
||||
NS_RGB( 34, 139, 34),
|
||||
NS_RGB(255, 0, 255),
|
||||
NS_RGB(220, 220, 220),
|
||||
NS_RGB(248, 248, 255),
|
||||
NS_RGB(255, 215, 0),
|
||||
NS_RGB(218, 165, 32),
|
||||
NS_RGB(128, 128, 128),
|
||||
NS_RGB( 0, 128, 0),
|
||||
NS_RGB(173, 255, 47),
|
||||
NS_RGB(240, 255, 240),
|
||||
NS_RGB(255, 105, 180),
|
||||
NS_RGB(205, 92, 92),
|
||||
NS_RGB( 75, 0, 130),
|
||||
NS_RGB(255, 255, 240),
|
||||
NS_RGB(240, 230, 140),
|
||||
NS_RGB(230, 230, 250),
|
||||
NS_RGB(255, 240, 245),
|
||||
NS_RGB(124, 252, 0),
|
||||
NS_RGB(255, 250, 205),
|
||||
NS_RGB(173, 216, 230),
|
||||
NS_RGB(240, 128, 128),
|
||||
NS_RGB(224, 255, 255),
|
||||
NS_RGB(250, 250, 210),
|
||||
NS_RGB(144, 238, 144),
|
||||
NS_RGB(211, 211, 211),
|
||||
NS_RGB(255, 182, 193),
|
||||
NS_RGB(255, 160, 122),
|
||||
NS_RGB( 32, 178, 170),
|
||||
NS_RGB(135, 206, 250),
|
||||
NS_RGB(119, 136, 153),
|
||||
NS_RGB(176, 196, 222),
|
||||
NS_RGB(255, 255, 224),
|
||||
NS_RGB( 0, 255, 0),
|
||||
NS_RGB( 50, 205, 50),
|
||||
NS_RGB(250, 240, 230),
|
||||
NS_RGB(255, 0, 255),
|
||||
NS_RGB(128, 0, 0),
|
||||
NS_RGB(102, 205, 170),
|
||||
NS_RGB( 0, 0, 205),
|
||||
NS_RGB(186, 85, 211),
|
||||
NS_RGB(147, 112, 219),
|
||||
NS_RGB( 60, 179, 113),
|
||||
NS_RGB(123, 104, 238),
|
||||
NS_RGB( 0, 250, 154),
|
||||
NS_RGB( 72, 209, 204),
|
||||
NS_RGB(199, 21, 133),
|
||||
NS_RGB( 25, 25, 112),
|
||||
NS_RGB(245, 255, 250),
|
||||
NS_RGB(255, 228, 225),
|
||||
NS_RGB(255, 228, 181),
|
||||
NS_RGB(255, 222, 173),
|
||||
NS_RGB( 0, 0, 128),
|
||||
NS_RGB(253, 245, 230),
|
||||
NS_RGB(128, 128, 0),
|
||||
NS_RGB(107, 142, 35),
|
||||
NS_RGB(255, 165, 0),
|
||||
NS_RGB(255, 69, 0),
|
||||
NS_RGB(218, 112, 214),
|
||||
NS_RGB(238, 232, 170),
|
||||
NS_RGB(152, 251, 152),
|
||||
NS_RGB(175, 238, 238),
|
||||
NS_RGB(219, 112, 147),
|
||||
NS_RGB(255, 239, 213),
|
||||
NS_RGB(255, 218, 185),
|
||||
NS_RGB(205, 133, 63),
|
||||
NS_RGB(255, 192, 203),
|
||||
NS_RGB(221, 160, 221),
|
||||
NS_RGB(176, 224, 230),
|
||||
NS_RGB(128, 0, 128),
|
||||
NS_RGB(255, 0, 0),
|
||||
NS_RGB(188, 143, 143),
|
||||
NS_RGB( 65, 105, 225),
|
||||
NS_RGB(139, 69, 19),
|
||||
NS_RGB(250, 128, 114),
|
||||
NS_RGB(244, 164, 96),
|
||||
NS_RGB( 46, 139, 87),
|
||||
NS_RGB(255, 245, 238),
|
||||
NS_RGB(160, 82, 45),
|
||||
NS_RGB(192, 192, 192),
|
||||
NS_RGB(135, 206, 235),
|
||||
NS_RGB(106, 90, 205),
|
||||
NS_RGB(112, 128, 144),
|
||||
NS_RGB(255, 250, 250),
|
||||
NS_RGB( 0, 255, 127),
|
||||
NS_RGB( 70, 130, 180),
|
||||
NS_RGB(210, 180, 140),
|
||||
NS_RGB( 0, 128, 128),
|
||||
NS_RGB(216, 191, 216),
|
||||
NS_RGB(255, 99, 71),
|
||||
NS_RGB( 64, 224, 208),
|
||||
NS_RGB(238, 130, 238),
|
||||
NS_RGB(245, 222, 179),
|
||||
NS_RGB(255, 255, 255),
|
||||
NS_RGB(245, 245, 245),
|
||||
NS_RGB(255, 255, 0),
|
||||
NS_RGB(154, 205, 50),
|
||||
};
|
||||
38
mozilla/gfx/src/nsCoord.h
Normal file
38
mozilla/gfx/src/nsCoord.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NSCOORD_H
|
||||
#define NSCOORD_H
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
/*
|
||||
* Basic type used for the geometry classes. By making it a typedef we can
|
||||
* easily change it in the future.
|
||||
*
|
||||
* All coordinates are maintained as signed 32-bit integers in the twips
|
||||
* coordinate space. A twip is 1/20th of a point, and there are 72 points per
|
||||
* inch.
|
||||
*
|
||||
* Twips are used because they are a device-independent unit of measure. See
|
||||
* header file nsUnitConversion.h for many useful macros to convert between
|
||||
* different units of measure.
|
||||
*/
|
||||
typedef PRInt32 nscoord;
|
||||
|
||||
#endif /* NSCOORD_H */
|
||||
80
mozilla/gfx/src/nsFont.cpp
Normal file
80
mozilla/gfx/src/nsFont.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsFont.h"
|
||||
#include "nsString.h"
|
||||
|
||||
nsFont::nsFont(const char* aName, PRUint8 aStyle, PRUint8 aVariant,
|
||||
PRUint16 aWeight, PRUint8 aDecoration, nscoord aSize)
|
||||
: name(aName)
|
||||
{
|
||||
style = aStyle;
|
||||
variant = aVariant;
|
||||
weight = aWeight;
|
||||
decorations = aDecoration;
|
||||
size = aSize;
|
||||
}
|
||||
|
||||
nsFont::nsFont(const nsString& aName, PRUint8 aStyle, PRUint8 aVariant,
|
||||
PRUint16 aWeight, PRUint8 aDecoration, nscoord aSize)
|
||||
: name(aName)
|
||||
{
|
||||
style = aStyle;
|
||||
variant = aVariant;
|
||||
weight = aWeight;
|
||||
decorations = aDecoration;
|
||||
size = aSize;
|
||||
}
|
||||
|
||||
nsFont::nsFont(const nsFont& aOther)
|
||||
: name(aOther.name)
|
||||
{
|
||||
style = aOther.style;
|
||||
variant = aOther.variant;
|
||||
weight = aOther.weight;
|
||||
decorations = aOther.decorations;
|
||||
size = aOther.size;
|
||||
}
|
||||
|
||||
nsFont::~nsFont()
|
||||
{
|
||||
}
|
||||
|
||||
PRBool nsFont::Equals(const nsFont& aOther) const
|
||||
{
|
||||
if ((style == aOther.style) &&
|
||||
(variant == aOther.variant) &&
|
||||
(weight == aOther.weight) &&
|
||||
(decorations == aOther.decorations) &&
|
||||
(size == aOther.size) &&
|
||||
name.EqualsIgnoreCase(aOther.name)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsFont& nsFont::operator=(const nsFont& aOther)
|
||||
{
|
||||
name = aOther.name;
|
||||
style = aOther.style;
|
||||
variant = aOther.variant;
|
||||
weight = aOther.weight;
|
||||
decorations = aOther.decorations;
|
||||
size = aOther.size;
|
||||
return *this;
|
||||
}
|
||||
86
mozilla/gfx/src/nsFont.h
Normal file
86
mozilla/gfx/src/nsFont.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsFont_h___
|
||||
#define nsFont_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsString.h"
|
||||
|
||||
// XXX we need a method to enumerate all of the possible fonts on the
|
||||
// system across family, weight, style, size, etc. But not here!
|
||||
|
||||
// Font structure.
|
||||
struct NS_GFX nsFont {
|
||||
// The family name of the font
|
||||
nsString name;
|
||||
|
||||
// The style of font (normal, italic, oblique)
|
||||
PRUint8 style;
|
||||
|
||||
// The variant of the font (normal, small-caps)
|
||||
PRUint8 variant;
|
||||
|
||||
// The weight of the font (0-999)
|
||||
PRUint16 weight;
|
||||
|
||||
// The decorations on the font (underline, overline,
|
||||
// line-through). The decorations can be binary or'd together.
|
||||
PRUint8 decorations;
|
||||
|
||||
// The size of the font, in nscoord units
|
||||
nscoord size;
|
||||
|
||||
// Initialize the font struct with an iso-latin1 name
|
||||
nsFont(const char* aName, PRUint8 aStyle, PRUint8 aVariant,
|
||||
PRUint16 aWeight, PRUint8 aDecoration, nscoord aSize);
|
||||
|
||||
// Initialize the font struct with a (potentially) unicode name
|
||||
nsFont(const nsString& aName, PRUint8 aStyle, PRUint8 aVariant,
|
||||
PRUint16 aWeight, PRUint8 aDecoration, nscoord aSize);
|
||||
|
||||
// Make a copy of the given font
|
||||
nsFont(const nsFont& aFont);
|
||||
|
||||
~nsFont();
|
||||
|
||||
PRBool operator==(const nsFont& aOther) const {
|
||||
return Equals(aOther);
|
||||
}
|
||||
|
||||
PRBool Equals(const nsFont& aOther) const ;
|
||||
|
||||
nsFont& operator=(const nsFont& aOther);
|
||||
};
|
||||
|
||||
#define NS_FONT_STYLE_NORMAL 0
|
||||
#define NS_FONT_STYLE_ITALIC 1
|
||||
#define NS_FONT_STYLE_OBLIQUE 2
|
||||
|
||||
#define NS_FONT_VARIANT_NORMAL 0
|
||||
#define NS_FONT_VARIANT_SMALL_CAPS 1
|
||||
|
||||
#define NS_FONT_DECORATION_UNDERLINE 0x1
|
||||
#define NS_FONT_DECORATION_OVERLINE 0x2
|
||||
#define NS_FONT_DECORATION_LINE_THROUGH 0x4
|
||||
|
||||
#define NS_FONT_WEIGHT_NORMAL 400
|
||||
#define NS_FONT_WEIGHT_BOLD 700
|
||||
|
||||
#endif /* nsFont_h___ */
|
||||
139
mozilla/gfx/src/nsFontCache.cpp
Normal file
139
mozilla/gfx/src/nsFontCache.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIFontCache.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFontCacheIID, NS_IFONT_CACHE_IID);
|
||||
|
||||
class FontCacheImpl : public nsIFontCache
|
||||
{
|
||||
public:
|
||||
FontCacheImpl();
|
||||
~FontCacheImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(nsIDeviceContext* aContext);
|
||||
virtual nsIDeviceContext* GetDeviceContext() const;
|
||||
virtual nsIFontMetrics* GetMetricsFor(const nsFont& aFont);
|
||||
virtual void Flush();
|
||||
|
||||
protected:
|
||||
nsVoidArray mFontMetrics;
|
||||
nsIDeviceContext *mContext;
|
||||
};
|
||||
|
||||
FontCacheImpl :: FontCacheImpl()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mContext = nsnull;
|
||||
}
|
||||
|
||||
FontCacheImpl :: ~FontCacheImpl()
|
||||
{
|
||||
Flush();
|
||||
NS_IF_RELEASE(mContext);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(FontCacheImpl, kIFontCacheIID)
|
||||
|
||||
nsresult FontCacheImpl :: Init(nsIDeviceContext* aContext)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aContext, "null ptr");
|
||||
mContext = aContext;
|
||||
NS_ADDREF(mContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDeviceContext* FontCacheImpl::GetDeviceContext() const
|
||||
{
|
||||
NS_IF_ADDREF(mContext);
|
||||
return mContext;
|
||||
}
|
||||
|
||||
nsIFontMetrics* FontCacheImpl :: GetMetricsFor(const nsFont& aFont)
|
||||
{
|
||||
nsIFontMetrics* fm;
|
||||
|
||||
// First check our cache
|
||||
PRInt32 n = mFontMetrics.Count();
|
||||
|
||||
for (PRInt32 cnt = 0; cnt < n; cnt++)
|
||||
{
|
||||
fm = (nsIFontMetrics*) mFontMetrics.ElementAt(cnt);
|
||||
|
||||
if (aFont.Equals(fm->GetFont()))
|
||||
{
|
||||
NS_ADDREF(fm);
|
||||
return fm;
|
||||
}
|
||||
}
|
||||
|
||||
// It's not in the cache. Get font metrics and then cache them.
|
||||
|
||||
static NS_DEFINE_IID(kFontMetricsCID, NS_FONT_METRICS_CID);
|
||||
static NS_DEFINE_IID(kFontMetricsIID, NS_IFONT_METRICS_IID);
|
||||
|
||||
nsresult rv = NSRepository::CreateInstance(kFontMetricsCID, nsnull,
|
||||
kFontMetricsIID, (void **)&fm);
|
||||
if (NS_OK != rv)
|
||||
return nsnull;
|
||||
|
||||
rv = fm->Init(aFont, mContext);
|
||||
|
||||
if (NS_OK != rv)
|
||||
return nsnull;/* XXX losing error code */
|
||||
|
||||
mFontMetrics.AppendElement(fm);
|
||||
|
||||
NS_ADDREF(fm);
|
||||
|
||||
return fm;
|
||||
}
|
||||
|
||||
void FontCacheImpl::Flush()
|
||||
{
|
||||
PRInt32 i, n = mFontMetrics.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
nsIFontMetrics* fm = (nsIFontMetrics*) mFontMetrics.ElementAt(i);
|
||||
NS_RELEASE(fm);
|
||||
}
|
||||
mFontMetrics.Clear();
|
||||
}
|
||||
|
||||
NS_GFX nsresult
|
||||
NS_NewFontCache(nsIFontCache **aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
|
||||
if (nsnull == aInstancePtrResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsIFontCache *cache = new FontCacheImpl();
|
||||
|
||||
if (nsnull == cache)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return cache->QueryInterface(kIFontCacheIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
42
mozilla/gfx/src/nsGfxCIID.h
Normal file
42
mozilla/gfx/src/nsGfxCIID.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsGfxCIID_h__
|
||||
#define nsGfxCIID_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsRepository.h"
|
||||
|
||||
#define NS_IMAGE_CID \
|
||||
{ 0x6049b260, 0xc1e6, 0x11d1, \
|
||||
{ 0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
#define NS_RENDERING_CONTEXT_CID \
|
||||
{ 0x6049b261, 0xc1e6, 0x11d1, \
|
||||
{ 0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
#define NS_DEVICE_CONTEXT_CID \
|
||||
{ 0x6049b262, 0xc1e6, 0x11d1, \
|
||||
{ 0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
#define NS_FONT_METRICS_CID \
|
||||
{ 0x6049b263, 0xc1e6, 0x11d1, \
|
||||
{ 0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
#endif
|
||||
92
mozilla/gfx/src/nsIDeviceContext.h
Normal file
92
mozilla/gfx/src/nsIDeviceContext.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIDeviceContext_h___
|
||||
#define nsIDeviceContext_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsIView;
|
||||
class nsIRenderingContext;
|
||||
class nsIFontCache;
|
||||
class nsIFontMetrics;
|
||||
class nsIWidget;
|
||||
struct nsFont;
|
||||
|
||||
#define NS_IDEVICE_CONTEXT_IID \
|
||||
{ 0x5931c580, 0xb917, 0x11d1, \
|
||||
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
class nsIDeviceContext : public nsISupports
|
||||
{
|
||||
public:
|
||||
virtual nsresult Init() = 0;
|
||||
|
||||
virtual nsIRenderingContext * CreateRenderingContext(nsIView *aView) = 0;
|
||||
virtual void InitRenderingContext(nsIRenderingContext *aContext, nsIWidget *aWindow) = 0;
|
||||
|
||||
//these are queries to figure out how large an output unit
|
||||
//(i.e. pixel) is in terms of twips (1/20 of a point)
|
||||
virtual float GetDevUnitsToTwips() const = 0;
|
||||
virtual float GetTwipsToDevUnits() const = 0;
|
||||
|
||||
//these are set by the object that created this
|
||||
//device context to define what the scale is
|
||||
//between the units used by the app and the
|
||||
//device units
|
||||
virtual void SetAppUnitsToDevUnits(float aAppUnits) = 0;
|
||||
virtual void SetDevUnitsToAppUnits(float aDevUnits) = 0;
|
||||
|
||||
//these are used to query the scale values defined
|
||||
//by the above Set*() methods
|
||||
virtual float GetAppUnitsToDevUnits() const = 0;
|
||||
virtual float GetDevUnitsToAppUnits() const = 0;
|
||||
|
||||
virtual float GetScrollBarWidth() const = 0;
|
||||
virtual float GetScrollBarHeight() const = 0;
|
||||
|
||||
//be sure to Relase() after you are done with the Get()
|
||||
virtual nsIFontCache * GetFontCache() = 0;
|
||||
virtual void FlushFontCache() = 0;
|
||||
|
||||
// Get the font metrics for a given font.
|
||||
virtual nsIFontMetrics* GetMetricsFor(const nsFont& aFont) = 0;
|
||||
|
||||
//get and set the document zoom value used for display-time
|
||||
//scaling. default is 1.0 (no zoom)
|
||||
virtual void SetZoom(float aZoom) = 0;
|
||||
virtual float GetZoom() const = 0;
|
||||
|
||||
//get a low level drawing surface for rendering. the rendering context
|
||||
//that is passed in is used to create the drawing surface if there isn't
|
||||
//already one in the device context. the drawing surface is then cached
|
||||
//in the device context for re-use.
|
||||
virtual nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext) = 0;
|
||||
|
||||
//functions for handling gamma correction of output device
|
||||
virtual float GetGamma(void) = 0;
|
||||
virtual void SetGamma(float aGamma) = 0;
|
||||
|
||||
//XXX the return from this really needs to be ref counted somehow. MMP
|
||||
virtual PRUint8 * GetGammaTable(void) = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIDeviceContext_h___ */
|
||||
68
mozilla/gfx/src/nsIFontCache.h
Normal file
68
mozilla/gfx/src/nsIFontCache.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIFontCache_h___
|
||||
#define nsIFontCache_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIFontMetrics;
|
||||
class nsIDeviceContext;
|
||||
struct nsFont;
|
||||
|
||||
// IID for the nsIFontCache interface
|
||||
#define NS_IFONT_CACHE_IID \
|
||||
{ 0x894758e0, 0xb49a, 0x11d1, \
|
||||
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
/**
|
||||
* Font cache interface. A font cache is bound to a particular device
|
||||
* context which it uses to realize the font metrics. The cache uses
|
||||
* the nsFont as a key.
|
||||
*/
|
||||
class nsIFontCache : public nsISupports
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialize the font cache. Call this after creating the font
|
||||
* cache and before trying to use it.
|
||||
*/
|
||||
virtual nsresult Init(nsIDeviceContext* aContext) = 0;
|
||||
|
||||
/**
|
||||
* Get the device context associated with this cache
|
||||
*/
|
||||
virtual nsIDeviceContext* GetDeviceContext() const = 0;
|
||||
|
||||
/**
|
||||
* Get metrics for a given font.
|
||||
*/
|
||||
virtual nsIFontMetrics* GetMetricsFor(const nsFont& aFont) = 0;
|
||||
|
||||
/**
|
||||
* Flush the cache.
|
||||
*/
|
||||
virtual void Flush() = 0;
|
||||
};
|
||||
|
||||
extern NS_GFX nsresult
|
||||
NS_NewFontCache(nsIFontCache **aInstancePtrResult);
|
||||
|
||||
#endif
|
||||
87
mozilla/gfx/src/nsIFontMetrics.h
Normal file
87
mozilla/gfx/src/nsIFontMetrics.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIFontMetrics_h___
|
||||
#define nsIFontMetrics_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsCoord.h"
|
||||
|
||||
struct nsFont;
|
||||
class nsString;
|
||||
class nsIDeviceContext;
|
||||
|
||||
// IID for the nsIFontMetrics interface
|
||||
#define NS_IFONT_METRICS_IID \
|
||||
{ 0xc74cb770, 0xa33e, 0x11d1, \
|
||||
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Native font handle
|
||||
typedef void* nsFontHandle;
|
||||
|
||||
// FontMetrics interface
|
||||
class nsIFontMetrics : public nsISupports
|
||||
{
|
||||
//what about encoding, where do we put that? MMP
|
||||
|
||||
public:
|
||||
//initializer
|
||||
virtual nsresult Init(const nsFont& aFont, nsIDeviceContext* aContext) = 0;
|
||||
|
||||
//get the width of an 8 bit char
|
||||
virtual nscoord GetWidth(char aC) = 0;
|
||||
|
||||
//get the width of a unicode char
|
||||
virtual nscoord GetWidth(PRUnichar aC) = 0;
|
||||
|
||||
//get the width of an nsString
|
||||
virtual nscoord GetWidth(const nsString& aString) = 0;
|
||||
|
||||
//get the width of 8 bit character string
|
||||
virtual nscoord GetWidth(const char *aString) = 0;
|
||||
|
||||
//get the width of a Unicode character string
|
||||
virtual nscoord GetWidth(const PRUnichar *aString, PRUint32 aLength) = 0;
|
||||
|
||||
//get the height as this font
|
||||
virtual nscoord GetHeight() = 0;
|
||||
|
||||
//get height - (ascent + descent)
|
||||
virtual nscoord GetLeading() = 0;
|
||||
|
||||
//get the maximum character ascent
|
||||
virtual nscoord GetMaxAscent() = 0;
|
||||
|
||||
//get the maximum character descent
|
||||
virtual nscoord GetMaxDescent() = 0;
|
||||
|
||||
//get the maximum character advance for the font
|
||||
virtual nscoord GetMaxAdvance() = 0;
|
||||
|
||||
//get the widths of the first 256 characters of the font
|
||||
virtual const nscoord *GetWidths() = 0;
|
||||
|
||||
//get the font associated width these metrics
|
||||
virtual const nsFont& GetFont() = 0;
|
||||
|
||||
virtual nsFontHandle GetFontHandle() = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIFontMetrics_h___ */
|
||||
233
mozilla/gfx/src/nsIImage.h
Normal file
233
mozilla/gfx/src/nsIImage.h
Normal file
@@ -0,0 +1,233 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIImage_h___
|
||||
#define nsIImage_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//I lifted this from the image lib. The difference is that
|
||||
//this uses nscolor instead of NI_RGB. Multiple color pollution
|
||||
//is a bad thing. MMP
|
||||
PRInt32 NumColors; // Number of colors in the colormap.
|
||||
// A negative value can be used to denote a
|
||||
// possibly non-unique set.
|
||||
//nscolor *Map; // Colormap colors.
|
||||
PRUint8 *Index; // NULL, if map is in index order, otherwise
|
||||
// specifies the indices of the map entries. */
|
||||
} nsColorMap;
|
||||
|
||||
typedef enum {
|
||||
nsMaskRequirements_kNoMask,
|
||||
nsMaskRequirements_kNeeds1Bit,
|
||||
nsMaskRequirements_kNeeds8Bit
|
||||
} nsMaskRequirements;
|
||||
|
||||
typedef enum{
|
||||
nsHighQual,
|
||||
nsMedQual,
|
||||
nsLowQual
|
||||
}nsBlendQuality;
|
||||
|
||||
|
||||
#define nsImageUpdateFlags_kColorMapChanged 0x1
|
||||
#define nsImageUpdateFlags_kBitsChanged 0x2
|
||||
|
||||
// IID for the nsIImage interface
|
||||
#define NS_IIMAGE_IID \
|
||||
{ 0x0b4faaa0, 0xaa3a, 0x11d1, \
|
||||
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
// Interface to Images
|
||||
class nsIImage : public nsISupports
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Build and initialize the pixelmap
|
||||
* @param aWidth The width in pixels of the desired pixelmap
|
||||
* @param aHeight The height in pixels of the desired pixelmap
|
||||
* @param aDepth The number of bits per pixel for the pixelmap
|
||||
* @param aMaskRequirements A flag indicating if a alpha mask should be allocated
|
||||
*/
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements) = 0;
|
||||
|
||||
/**
|
||||
* Get the width for the pixelmap
|
||||
@return The width in pixels for the pixelmap
|
||||
*/
|
||||
virtual PRInt32 GetWidth() = 0;
|
||||
|
||||
/**
|
||||
* Get the height for the pixelmap
|
||||
@return The height in pixels for the pixelmap
|
||||
*/
|
||||
virtual PRInt32 GetHeight() = 0;
|
||||
|
||||
/**
|
||||
* Get a pointer to the bits for the pixelmap, only if it is not optimized
|
||||
@return address of the DIB pixel array
|
||||
*/
|
||||
virtual PRUint8 * GetBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes needed to get to the next scanline for the pixelmap
|
||||
@return The number of bytes in each scanline
|
||||
*/
|
||||
virtual PRInt32 GetLineStride() = 0;
|
||||
|
||||
/**
|
||||
* Get a pointer to the bits for the alpha mask
|
||||
@return address of the alpha mask pixel array
|
||||
*/
|
||||
virtual PRUint8 * GetAlphaBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the width of the alpha mask
|
||||
@return The width in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaWidth() = 0;
|
||||
|
||||
/**
|
||||
* Get the height of the alpha mask
|
||||
@return The width in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaHeight() = 0;
|
||||
|
||||
/**
|
||||
* Get the x location of the upper corner of the alpha mask
|
||||
@return The x location in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaXLoc() = 0;
|
||||
|
||||
/**
|
||||
* Get the y location of the upper corner of the alpha mask
|
||||
@return The y location in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaYLoc() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes needed to get to the next scanline for the alpha mask
|
||||
@return The number of bytes in each scanline
|
||||
*/
|
||||
virtual PRInt32 GetAlphaLineStride() = 0;
|
||||
|
||||
/**
|
||||
* Will update a pixelmaps color table
|
||||
@param aFlags Used to pass in parameters for the update
|
||||
@param aUpdateRect The rectangle to update
|
||||
*/
|
||||
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect) = 0;
|
||||
|
||||
/**
|
||||
* Returns if the pixelmap has been converted to an optimized pixelmap
|
||||
@return If true, it is optimized
|
||||
*/
|
||||
virtual PRBool IsOptimized() = 0;
|
||||
|
||||
/**
|
||||
* Converted this pixelmap to an optimized pixelmap for the device
|
||||
@param aSurface The surface to optimize for
|
||||
@return the result of the operation, if NS_OK, then the pixelmap is optimized
|
||||
*/
|
||||
virtual nsresult Optimize(nsDrawingSurface aSurface) = 0;
|
||||
|
||||
/**
|
||||
* Get the colormap for the pixelmap
|
||||
@return if non null, the colormap for the pixelmap,otherwise the image is not color mapped
|
||||
*/
|
||||
virtual nsColorMap * GetColorMap() = 0;
|
||||
|
||||
/**
|
||||
* BitBlit the pixelmap to a device, the source can be scale to the dest
|
||||
@param aSurface the surface to blit to
|
||||
@param aX The destination horizontal location
|
||||
@param aY The destination vertical location
|
||||
@param aWidth The destination width of the pixelmap
|
||||
@param aHeight The destination height of the pixelmap
|
||||
@return if TRUE, no errors
|
||||
*/
|
||||
virtual PRBool Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) = 0;
|
||||
|
||||
/**
|
||||
* BitBlit the pixelmap to a device, the source and dest can be scaled
|
||||
* @param aSurface the surface to blit to
|
||||
* @param aSX The source width of the pixelmap
|
||||
* @param aSY The source vertical location
|
||||
* @param aSWidth The source width of the pixelmap
|
||||
* @param aSHeight The source height of the pixelmap
|
||||
* @param aDX The destination horizontal location
|
||||
* @param aDY The destination vertical location
|
||||
* @param aDWidth The destination width of the pixelmap
|
||||
* @param aDHeight The destination height of the pixelmap
|
||||
* @return if TRUE, no errors
|
||||
*/
|
||||
virtual PRBool Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Composite this image with the passed in image using the alpha mask
|
||||
* @param aTheImage The image to blend into this image
|
||||
* @param aULLocation The upper left coordinate to place the passed in image
|
||||
*/
|
||||
virtual void CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation,nsBlendQuality aQuality) = 0;
|
||||
|
||||
/**
|
||||
* Build an alpha mask using this image
|
||||
* @param aTheMaskImage The image to build the mask from
|
||||
* @return true if the mask was set up.
|
||||
*/
|
||||
virtual PRBool SetAlphaMask(nsIImage *aTheMask) = 0;
|
||||
|
||||
/**
|
||||
* Move the alpha mask to this absolute location
|
||||
* @param the horiztonal location
|
||||
* @param the vertical location
|
||||
*/
|
||||
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate this image and pass back new object to it
|
||||
* @param TheImage is the image to duplicate into this object
|
||||
* @return the new image
|
||||
*/
|
||||
virtual nsIImage* DuplicateImage() = 0;
|
||||
|
||||
//get the color space metrics for this image
|
||||
//virtual NI_ColorSpec * GetColorSpec() = 0; fix
|
||||
|
||||
//get the color which should be considered transparent.
|
||||
//if this image is color mapped, this value will be an
|
||||
//index into the color map. hokey? yes, but it avoids
|
||||
//another silly api or struct.
|
||||
//virtual nscolor GetTransparentColor() = 0; fix.
|
||||
};
|
||||
|
||||
//change notification API flag bits
|
||||
#define NS_IMAGE_UPDATE_COLORMAP 1
|
||||
#define NS_IMAGE_UPDATE_PIXELS 2
|
||||
#define NS_IMAGE_UPDATE_ALPHA 4
|
||||
|
||||
#endif
|
||||
118
mozilla/gfx/src/nsIImageGroup.h
Normal file
118
mozilla/gfx/src/nsIImageGroup.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIImageGroup_h___
|
||||
#define nsIImageGroup_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsISupports.h"
|
||||
#include "nscore.h"
|
||||
#include "nsColor.h"
|
||||
|
||||
class nsIImageGroupObserver;
|
||||
class nsIImageRequestObserver;
|
||||
class nsIImageRequest;
|
||||
class nsIRenderingContext;
|
||||
|
||||
/** For important images, like backdrops. */
|
||||
#define nsImageLoadFlags_kHighPriority 0x01
|
||||
/** Don't throw this image out of cache. */
|
||||
#define nsImageLoadFlags_kSticky 0x02
|
||||
/** Don't get image out of image cache. */
|
||||
#define nsImageLoadFlags_kBypassCache 0x04
|
||||
/** Don't load if image cache misses. */
|
||||
#define nsImageLoadFlags_kOnlyFromCache 0x08
|
||||
|
||||
// IID for the nsIImageGroup interface
|
||||
#define NS_IIMAGEGROUP_IID \
|
||||
{ 0xbe927e40, 0xaeaa, 0x11d1, \
|
||||
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
|
||||
|
||||
/**
|
||||
*
|
||||
* Image group. A convenient way to group a set of image load requests
|
||||
* and control them as a group.
|
||||
*/
|
||||
class nsIImageGroup : public nsISupports
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialize an image group with a rendering context. All images
|
||||
* in this group will be decoded for the specified rendering context.
|
||||
*/
|
||||
virtual nsresult Init(nsIRenderingContext *aRenderingContext) = 0;
|
||||
|
||||
/**
|
||||
* Add an observers to be informed of image group notifications.
|
||||
*
|
||||
* @param aObserver - An observer to add to the observer list.
|
||||
* @param boolean indicating whether addition was successful.
|
||||
*/
|
||||
virtual PRBool AddObserver(nsIImageGroupObserver *aObserver) = 0;
|
||||
|
||||
/**
|
||||
* Remove a previously added observer from the observer list.
|
||||
*
|
||||
* @param aObserver - An observer to remove from the observer list.
|
||||
* @param boolean indicating whether the removal was successful.
|
||||
*/
|
||||
virtual PRBool RemoveObserver(nsIImageGroupObserver *aObserver) = 0;
|
||||
|
||||
/**
|
||||
* Fetch the image corresponding to the specified URL.
|
||||
*
|
||||
* @param aUrl - the URL of the image to be loaded.
|
||||
* @param aObserver - the observer is notified at significant
|
||||
* points in image loading.
|
||||
* @param aWidth, aHeight - These parameters specify the target
|
||||
* dimensions of the image. The image will be stretched
|
||||
* horizontally, vertically or both to meet these parameters.
|
||||
* If both width and height are zero, the image is decoded
|
||||
* using its "natural" size. If only one of width and height
|
||||
* is zero, the image is scaled to the provided dimension, with
|
||||
* the unspecified dimension scaled to maintain the image's
|
||||
* original aspect ratio.
|
||||
* @param aBackgroundColor - If the background color is NULL, a mask
|
||||
* will be generated for any transparent images. If background
|
||||
* color is non-NULL, it indicates the RGB value to be painted
|
||||
* into the image for "transparent" areas of the image, in which
|
||||
* case no mask is created. This is intended for backdrops and
|
||||
* printing.
|
||||
* @param aFlags - image loading flags are specified above
|
||||
*
|
||||
* @return the resulting image request object.
|
||||
*/
|
||||
virtual nsIImageRequest* GetImage(const char* aUrl,
|
||||
nsIImageRequestObserver *aObserver,
|
||||
nscolor aBackgroundColor,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
PRUint32 aFlags) = 0;
|
||||
|
||||
/**
|
||||
* Halt decoding of images or animation without destroying associated
|
||||
* pixmap data. All ImageRequests created with this ImageGroup
|
||||
* are interrupted.
|
||||
*/
|
||||
virtual void Interrupt(void) = 0;
|
||||
};
|
||||
|
||||
/// Factory method for creating an image group
|
||||
extern NS_GFX nsresult
|
||||
NS_NewImageGroup(nsIImageGroup **aInstancePtrResult);
|
||||
|
||||
#endif
|
||||
83
mozilla/gfx/src/nsIImageManager.h
Normal file
83
mozilla/gfx/src/nsIImageManager.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIImageManager_h___
|
||||
#define nsIImageManager_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsISupports.h"
|
||||
#include "nscore.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
nsImageType_kUnknown = 0,
|
||||
nsImageType_kGIF = 1,
|
||||
nsImageType_kXBM = 2,
|
||||
nsImageType_kJPEG = 3,
|
||||
nsImageType_kPPM = 4,
|
||||
nsImageType_kPNG = 5
|
||||
} nsImageType;
|
||||
|
||||
// IID for the nsIImageManager interface
|
||||
#define NS_IIMAGEMANAGER_IID \
|
||||
{ 0x9f327100, 0xad5a, 0x11d1, \
|
||||
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
|
||||
|
||||
/**
|
||||
*
|
||||
* Image manager. There is only a single instance, returned when invoking
|
||||
* the factory instantiation method. A user of the image library should
|
||||
* hold on to the singleton image manager.
|
||||
*/
|
||||
class nsIImageManager : public nsISupports
|
||||
{
|
||||
public:
|
||||
/// Initialization method to be called before use
|
||||
virtual nsresult Init() = 0;
|
||||
|
||||
/// Set the size (in bytes) image cache maintained by the image manager
|
||||
virtual void SetCacheSize(PRInt32 aCacheSize) = 0;
|
||||
|
||||
/// @return the current size of the image cache (in bytes)
|
||||
virtual PRInt32 GetCacheSize(void) = 0;
|
||||
|
||||
/**
|
||||
* Attempts to release some memory by freeing an image from the image
|
||||
* cache. This may not always be possible either because all images
|
||||
* in the cache are in use or because the cache is empty.
|
||||
*
|
||||
* @return the new approximate size of the imagelib cache.
|
||||
*/
|
||||
virtual PRInt32 ShrinkCache(void) = 0;
|
||||
|
||||
/**
|
||||
* Determine the type of the image, based on the first few bytes of data.
|
||||
*
|
||||
* @param buf - a buffer of image data
|
||||
* @param length - the length of the buffer
|
||||
*
|
||||
* @return the type of the image, if known
|
||||
*/
|
||||
virtual nsImageType GetImageType(const char *buf, PRInt32 length) = 0;
|
||||
};
|
||||
|
||||
/// Factory method to get a reference to the singleton image manager
|
||||
extern NS_GFX nsresult
|
||||
NS_NewImageManager(nsIImageManager **aInstancePtrResult);
|
||||
|
||||
#endif
|
||||
167
mozilla/gfx/src/nsIImageObserver.h
Normal file
167
mozilla/gfx/src/nsIImageObserver.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIImageObserver_h___
|
||||
#define nsIImageObserver_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsISupports.h"
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIImage;
|
||||
class nsIImageRequest;
|
||||
class nsIImageGroup;
|
||||
|
||||
/// Image request notifications
|
||||
typedef enum {
|
||||
nsImageNotification_kStartURL, // Start of decode/display for URL.
|
||||
nsImageNotification_kDescription, // Availability of image description.
|
||||
nsImageNotification_kDimensions, // Availability of image dimensions.
|
||||
nsImageNotification_kIsTransparent, // This image is transparent.
|
||||
nsImageNotification_kPixmapUpdate, // Change in a rectangular area of
|
||||
// pixels.
|
||||
nsImageNotification_kFrameComplete, // Completion of a frame of an animated
|
||||
// image.
|
||||
nsImageNotification_kProgress, // Notification of percentage decoded.
|
||||
nsImageNotification_kImageComplete, // Completion of image decoding. There
|
||||
// may be multiple instances of this
|
||||
// event per URL due to server push,
|
||||
// client pull or looping GIF animation.
|
||||
nsImageNotification_kStopURL, // Completion of decode/display for URL.
|
||||
nsImageNotification_kImageDestroyed,// Finalization of an image request. This
|
||||
// is an indication to perform any
|
||||
// observer related cleanup.
|
||||
nsImageNotification_kAborted, // Image decode was aborted by either
|
||||
// the network library or Interrupt().
|
||||
nsImageNotification_kInternalImage, // Internal image icon.
|
||||
} nsImageNotification;
|
||||
|
||||
/// Image group notifications
|
||||
typedef enum {
|
||||
|
||||
// Start of image loading. Sent when a loading image is
|
||||
// added to an image group which currently has no loading images.
|
||||
nsImageGroupNotification_kStartedLoading,
|
||||
|
||||
// Some images were aborted. A finished loading message will not be sent
|
||||
// until the aborted images have been destroyed.
|
||||
nsImageGroupNotification_kAbortedLoading,
|
||||
|
||||
// End of image loading. Sent when the last of the images currently
|
||||
// in the image group has finished loading.
|
||||
nsImageGroupNotification_kFinishedLoading,
|
||||
|
||||
// Start of image looping. Sent when an animated image starts looping in
|
||||
// an image group which currently has no looping animations.
|
||||
nsImageGroupNotification_kStartedLooping,
|
||||
|
||||
// End of image looping. Sent when the last of the images currently in
|
||||
// the image group has finished looping.
|
||||
nsImageGroupNotification_kFinishedLooping
|
||||
|
||||
} nsImageGroupNotification;
|
||||
|
||||
/// Image loading errors
|
||||
typedef enum {
|
||||
nsImageError_kNotInCache, // Image URL not available in cache when
|
||||
// kOnlyFromCache flag was set.
|
||||
nsImageError_kNoData, // Network library unable to fetch
|
||||
// provided URL.
|
||||
nsImageError_kImageDataCorrupt, // Checksum error of some kind in
|
||||
// image data.
|
||||
nsImageError_kImageDataTruncated, // Missing data at end of stream.
|
||||
nsImageError_kImageDataIllegal, // Generic image data error.
|
||||
nsImageError_kInternalError // Internal Image Library error.
|
||||
|
||||
} nsImageError;
|
||||
|
||||
// IID for the nsIImageRequestObserver interface
|
||||
#define NS_IIMAGEREQUESTOBSERVER_IID \
|
||||
{ 0x965467a0, 0xb8f4, 0x11d1, \
|
||||
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
|
||||
|
||||
// IID for the nsIImageGroupObserver interface
|
||||
#define NS_IIMAGEGROUPOBSERVER_IID \
|
||||
{ 0xb3cad300, 0xb8f4, 0x11d1, \
|
||||
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
|
||||
|
||||
/**
|
||||
* Image request observer interface. The implementor will be notified
|
||||
* of significant loading events or loading errors.
|
||||
*/
|
||||
class nsIImageRequestObserver : public nsISupports {
|
||||
public:
|
||||
/**
|
||||
* Notify the observer of some significant image event. The parameter
|
||||
* values depend on the notification type as specified below.
|
||||
*
|
||||
* kDescription - aParam3 is a string containing the human readable
|
||||
* description of an image, e.g. "GIF89a 320 x 240 pixels".
|
||||
* The string storage is static, so it must be copied if
|
||||
* it is to be preserved after the call to the observer.
|
||||
* kDimensions - aParam1 and aParam2 are the width and height respectively
|
||||
* of the image.
|
||||
* kPixmapUpdate - aParame3 is a pointer to a nsRect struct containing the
|
||||
* rectangular area of pixels which has been modified by
|
||||
* the image library. This notification enables the
|
||||
* client to drive the progressive display of the image.
|
||||
* kProgress - aParam1 represents the estimated percentage decoded. This
|
||||
* notification occurs at unspecified intervals. Provided
|
||||
* that decoding proceeds without error, it is guaranteed that
|
||||
* notification will take place on completion with a
|
||||
* percent_progress value of 100.
|
||||
*
|
||||
* @param aImageRequest - the image request in question
|
||||
* @param aImage - the corresponding image object
|
||||
* @param aNotificationType - the type of notification
|
||||
* @param aParam1, aParam2, aParam3 - additional information as described
|
||||
* above.
|
||||
*/
|
||||
virtual void Notify(nsIImageRequest *aImageRequest,
|
||||
nsIImage *aImage,
|
||||
nsImageNotification aNotificationType,
|
||||
PRInt32 aParam1, PRInt32 aParam2,
|
||||
void *aParam3)=0;
|
||||
|
||||
/**
|
||||
* Notify the observer of an error during image loading.
|
||||
*
|
||||
* @param aImageRequest - the image request in question
|
||||
* @param aErrorType - the error code
|
||||
*/
|
||||
virtual void NotifyError(nsIImageRequest *aImageRequest,
|
||||
nsImageError aErrorType)=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Image group observer interface. The implementor will be notified
|
||||
* of significant image group events.
|
||||
*/
|
||||
class nsIImageGroupObserver : public nsISupports {
|
||||
public:
|
||||
/**
|
||||
* Notify the observer of some significant image group event.
|
||||
*
|
||||
* @param aImageGroup - the image group in question
|
||||
* @param aNotificationType - the notification code
|
||||
*/
|
||||
virtual void Notify(nsIImageGroup *aImageGroup,
|
||||
nsImageGroupNotification aNotificationType)=0;
|
||||
};
|
||||
|
||||
#endif
|
||||
73
mozilla/gfx/src/nsIImageRequest.h
Normal file
73
mozilla/gfx/src/nsIImageRequest.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIImageRequest_h___
|
||||
#define nsIImageRequest_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsISupports.h"
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIImageRequestObserver;
|
||||
class nsIImage;
|
||||
|
||||
// IID for the nsIImageRequest interface
|
||||
#define NS_IIMAGEREQUEST_IID \
|
||||
{ 0xc31444c0, 0xaec9, 0x11d1, \
|
||||
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
|
||||
|
||||
/**
|
||||
*
|
||||
* An image request generated as a result of invoking the
|
||||
* <code>GetImage</code> method of the <code>nsIImageGroup</code>
|
||||
* interface.
|
||||
*/
|
||||
class nsIImageRequest : public nsISupports {
|
||||
public:
|
||||
/// @return the image object associated with the request.
|
||||
virtual nsIImage* GetImage() = 0;
|
||||
|
||||
/**
|
||||
* Returns the natural dimensions of the image. Returns 0,0
|
||||
* if the dimensions are unknown.
|
||||
*
|
||||
* @param aWidth, aHeight - pointers to integers to be filled in with
|
||||
* the dimensions.
|
||||
*/
|
||||
virtual void GetNaturalDimensions(PRUint32 *aWidth, PRUint32 *aHeight) = 0;
|
||||
|
||||
/**
|
||||
* Add an observers to be informed of image loading notifications.
|
||||
*
|
||||
* @param aObserver - An observer to add to the observer list.
|
||||
* @param boolean indicating whether addition was successful.
|
||||
*/
|
||||
virtual PRBool AddObserver(nsIImageRequestObserver *aObserver) = 0;
|
||||
|
||||
/**
|
||||
* Remove a previously added observer from the observer list.
|
||||
*
|
||||
* @param aObserver - An observer to remove from the observer list.
|
||||
* @param boolean indicating whether the removal was successful.
|
||||
*/
|
||||
virtual PRBool RemoveObserver(nsIImageRequestObserver *aObserver) = 0;
|
||||
|
||||
/// Interrupt loading of just this image.
|
||||
virtual void Interrupt() = 0;
|
||||
};
|
||||
#endif
|
||||
378
mozilla/gfx/src/nsIRenderingContext.h
Normal file
378
mozilla/gfx/src/nsIRenderingContext.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIRenderingContext_h___
|
||||
#define nsIRenderingContext_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsCoord.h"
|
||||
|
||||
class nsIWidget;
|
||||
class nsIFontMetrics;
|
||||
class nsIImage;
|
||||
class nsTransform2D;
|
||||
class nsString;
|
||||
class nsIFontCache;
|
||||
class nsIDeviceContext;
|
||||
|
||||
struct nsFont;
|
||||
struct nsPoint;
|
||||
struct nsRect;
|
||||
|
||||
// IID for the nsIRenderingContext interface
|
||||
#define NS_IRENDERING_CONTEXT_IID \
|
||||
{ 0x7fd8c0f0, 0xa265, 0x11d1, \
|
||||
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//a cross platform way of specifying a navite rendering context
|
||||
typedef void * nsDrawingSurface;
|
||||
|
||||
// RenderingContext interface
|
||||
class nsIRenderingContext : public nsISupports
|
||||
{
|
||||
public:
|
||||
//TBD: bind/unbind, transformation of scalars (hacky),
|
||||
//potential drawmode for selection, polygons. MMP
|
||||
|
||||
/**
|
||||
* Initialize the RenderingContext
|
||||
* @param aContext the device context to use.
|
||||
* @param aWidget the widget to hook up to
|
||||
* @result The result of the initialization, NS_Ok if no errors
|
||||
*/
|
||||
virtual nsresult Init(nsIDeviceContext* aContext,nsIWidget *aWidget) = 0;
|
||||
|
||||
/**
|
||||
* Initialize the RenderingContext
|
||||
* @param aContext the device context to use for the drawing.
|
||||
* @param aSurface the surface to draw into
|
||||
* @result The result of the initialization, NS_Ok if no errors
|
||||
*/
|
||||
virtual nsresult Init(nsIDeviceContext* aContext,nsDrawingSurface aSurface) = 0;
|
||||
|
||||
/**
|
||||
* Reset the rendering context
|
||||
*/
|
||||
virtual void Reset() = 0;
|
||||
|
||||
/**
|
||||
* Get the DeviceContext that this RenderingContext was initialized with
|
||||
* @result the device context
|
||||
*/
|
||||
virtual nsIDeviceContext * GetDeviceContext(void) = 0;
|
||||
|
||||
/**
|
||||
* Selects an offscreen drawing surface into the RenderingContext to draw to.
|
||||
* @param aSurface is the offscreen surface we are going to draw to.
|
||||
*/
|
||||
virtual nsresult SelectOffScreenDrawingSurface(nsDrawingSurface aSurface) = 0;
|
||||
|
||||
/**
|
||||
* Save a graphical state onto a stack.
|
||||
*/
|
||||
virtual void PushState() = 0;
|
||||
|
||||
/**
|
||||
* Get and and set RenderingContext to this graphical state
|
||||
*/
|
||||
virtual void PopState() = 0;
|
||||
|
||||
/**
|
||||
* Tells if a given rectangle is visible within the rendering context
|
||||
* @param aRect is the rectangle that will be checked for visiblity
|
||||
* @result If true, that rectanglular area is visable.
|
||||
*/
|
||||
virtual PRBool IsVisibleRect(const nsRect& aRect) = 0;
|
||||
|
||||
/**
|
||||
* Sets the clipping for the RenderingContext to the passed in rectangle
|
||||
* @param aRect The rectangle to set the clipping rectangle to
|
||||
* @param aIntersect A boolean, if true will cause aRect to be intersected with exsiting clip rects
|
||||
*/
|
||||
virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect) = 0;
|
||||
|
||||
/**
|
||||
* Gets the clipping rectangle of the RenderingContext
|
||||
* @return The clipping rectangle for the RenderingContext
|
||||
*/
|
||||
virtual const nsRect& GetClipRect() = 0;
|
||||
|
||||
/**
|
||||
* Sets the forground color for the RenderingContext
|
||||
* @param aColor The color to set the RenderingContext to
|
||||
*/
|
||||
virtual void SetColor(nscolor aColor) = 0;
|
||||
|
||||
/**
|
||||
* Get the forground color for the RenderingContext
|
||||
* @return The current forground color of the RenderingContext
|
||||
*/
|
||||
virtual nscolor GetColor() const = 0;
|
||||
|
||||
/**
|
||||
* Sets the font for the RenderingContext
|
||||
* @param aFont The font to use in the RenderingContext
|
||||
*/
|
||||
virtual void SetFont(const nsFont& aFont) = 0;
|
||||
|
||||
/**
|
||||
* Get the current font for the RenderingContext
|
||||
* @return The current font of the RenderingContext
|
||||
*/
|
||||
virtual const nsFont& GetFont() = 0;
|
||||
|
||||
/**
|
||||
* Get the current fontmetrics for the RenderingContext
|
||||
* @return The current font of the RenderingContext
|
||||
*/
|
||||
virtual nsIFontMetrics* GetFontMetrics() = 0;
|
||||
|
||||
/**
|
||||
* Add in a translate to the RenderingContext's transformation matrix
|
||||
* @param aX The horizontal translation
|
||||
* @param aY The vertical translation
|
||||
*/
|
||||
virtual void Translate(nscoord aX, nscoord aY) = 0;
|
||||
|
||||
/**
|
||||
* Add in a scale to the RenderingContext's transformation matrix
|
||||
* @param aX The horizontal scale
|
||||
* @param aY The vertical scale
|
||||
*/
|
||||
virtual void Scale(float aSx, float aSy) = 0;
|
||||
|
||||
/**
|
||||
* Get the current transformation matrix for the RenderingContext
|
||||
* @return The transformation matrix for the RenderingContext
|
||||
*/
|
||||
virtual nsTransform2D * GetCurrentTransform() = 0;
|
||||
|
||||
/**
|
||||
* Create an offscreen drawing surface compatible with this RenderingContext
|
||||
* @param aBounds A rectangle representing the size for the drawing surface.
|
||||
* if nsnull then a bitmap will not be created and associated
|
||||
* with the new drawing surface
|
||||
* @return A nsDrawingSurface
|
||||
*/
|
||||
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds) = 0;
|
||||
|
||||
/**
|
||||
* Destroy a drawing surface created by CreateDrawingSurface()
|
||||
* @param aDS A drawing surface to destroy
|
||||
*/
|
||||
virtual void DestroyDrawingSurface(nsDrawingSurface aDS) = 0;
|
||||
|
||||
/**
|
||||
* Draw a line
|
||||
* @param aXO starting horiztonal coord in twips
|
||||
* @param aY0 starting vertical coord in twips
|
||||
* @param aX1 end horiztonal coord in twips
|
||||
* @param aY1 end vertical coord in twips
|
||||
*/
|
||||
virtual void DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1) = 0;
|
||||
|
||||
/**
|
||||
* Draw a rectangle
|
||||
* @param aRect The rectangle to draw
|
||||
*/
|
||||
virtual void DrawRect(const nsRect& aRect) = 0;
|
||||
|
||||
/**
|
||||
* Draw a rectangle
|
||||
* @param aX Horizontal left Coordinate in twips
|
||||
* @param aY Vertical top Coordinate in twips
|
||||
* @param aWidth Width of rectangle in twips
|
||||
* @param aHeight Height of rectangle in twips
|
||||
*/
|
||||
virtual void DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) = 0;
|
||||
|
||||
/**
|
||||
* Fill a rectangle in the current foreground color
|
||||
* @param aRect The rectangle to draw
|
||||
*/
|
||||
virtual void FillRect(const nsRect& aRect) = 0;
|
||||
|
||||
/**
|
||||
* Fill a rectangle in the current foreground color
|
||||
* @param aX Horizontal left Coordinate in twips
|
||||
* @param aY Vertical top Coordinate in twips
|
||||
* @param aWidth Width of rectangle in twips
|
||||
* @param aHeight Height of rectangle in twips
|
||||
*/
|
||||
virtual void FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) = 0;
|
||||
|
||||
/**
|
||||
* Draw a poly in the current foreground color
|
||||
* @param aPoints points to use for the drawing, last must equal first
|
||||
* @param aNumPonts number of points in the polygon
|
||||
*/
|
||||
virtual void DrawPolygon(nsPoint aPoints[], PRInt32 aNumPoints) = 0;
|
||||
|
||||
/**
|
||||
* Fill a poly in the current foreground color
|
||||
* @param aPoints points to use for the drawing, last must equal first
|
||||
* @param aNumPonts number of points in the polygon
|
||||
*/
|
||||
virtual void FillPolygon(nsPoint aPoints[], PRInt32 aNumPoints) = 0;
|
||||
|
||||
/**
|
||||
* Draw an ellipse in the current foreground color
|
||||
* @param aRect The rectangle define bounds of ellipse to draw
|
||||
*/
|
||||
virtual void DrawEllipse(const nsRect& aRect) = 0;
|
||||
|
||||
/**
|
||||
* Draw an ellipse in the current foreground color
|
||||
* @param aX Horizontal left Coordinate in twips
|
||||
* @param aY Vertical top Coordinate in twips
|
||||
* @param aWidth Width of horizontal axis in twips
|
||||
* @param aHeight Height of vertical axis in twips
|
||||
*/
|
||||
virtual void DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) = 0;
|
||||
|
||||
/**
|
||||
* Fill an ellipse in the current foreground color
|
||||
* @param aRect The rectangle define bounds of ellipse to draw
|
||||
*/
|
||||
virtual void FillEllipse(const nsRect& aRect) = 0;
|
||||
/**
|
||||
* Fill an ellipse in the current foreground color
|
||||
* @param aX Horizontal left Coordinate in twips
|
||||
* @param aY Vertical top Coordinate in twips
|
||||
* @param aWidth Width of horizontal axis in twips
|
||||
* @param aHeight Height of vertical axis in twips
|
||||
*/
|
||||
virtual void FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) = 0;
|
||||
/**
|
||||
* Draw an arc in the current forground color
|
||||
* @param aRect The rectangle define bounds of ellipse to use
|
||||
* @param aStartAngle the starting angle of the arc, in the ellipse
|
||||
* @param aEndAngle The ending angle of the arc, in the ellipse
|
||||
*/
|
||||
virtual void DrawArc(const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle) = 0;
|
||||
/**
|
||||
* Draw an arc in the current forground color
|
||||
* @param aX Horizontal left Coordinate in twips
|
||||
* @param aY Vertical top Coordinate in twips
|
||||
* @param aWidth Width of horizontal axis in twips
|
||||
* @param aHeight Height of vertical axis in twips
|
||||
* @param aStartAngle the starting angle of the arc, in the ellipse
|
||||
* @param aEndAngle The ending angle of the arc, in the ellipse
|
||||
*/
|
||||
virtual void DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle) = 0;
|
||||
/**
|
||||
* Fill an arc in the current forground color
|
||||
* @param aRect The rectangle define bounds of ellipse to use
|
||||
* @param aStartAngle the starting angle of the arc, in the ellipse
|
||||
* @param aEndAngle The ending angle of the arc, in the ellipse
|
||||
*/
|
||||
virtual void FillArc(const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle) = 0;
|
||||
/**
|
||||
* Fill an arc in the current forground color
|
||||
* @param aX Horizontal left Coordinate in twips
|
||||
* @param aY Vertical top Coordinate in twips
|
||||
* @param aWidth Width of horizontal axis in twips
|
||||
* @param aHeight Height of vertical axis in twips
|
||||
* @param aStartAngle the starting angle of the arc, in the ellipse
|
||||
* @param aEndAngle The ending angle of the arc, in the ellipse
|
||||
*/
|
||||
virtual void FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle) = 0;
|
||||
|
||||
/**
|
||||
* Draw a string in the RenderingContext
|
||||
* @param aString The string to draw
|
||||
* @param aLength The length of the aString
|
||||
* @param aX Horizontal starting point of baseline
|
||||
* @param aY Vertical starting point of baseline.
|
||||
* @param aWidth Width of the underline
|
||||
*/
|
||||
virtual void DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
nscoord aWidth) = 0;
|
||||
/**
|
||||
* Draw a string in the RenderingContext
|
||||
* @param aString A PRUnichar of the string
|
||||
* @param aLength The length of the aString
|
||||
* @param aX Horizontal starting point of baseline
|
||||
* @param aY Vertical starting point of baseline.
|
||||
* @param aWidth length in twips of the underline
|
||||
*/
|
||||
virtual void DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
nscoord aWidth) = 0;
|
||||
/**
|
||||
* Draw a string in the RenderingContext
|
||||
* @param aString A nsString of the string
|
||||
* @param aX Horizontal starting point of baseline
|
||||
* @param aY Vertical starting point of baseline.
|
||||
* @param aWidth Width of the underline
|
||||
*/
|
||||
virtual void DrawString(const nsString& aString, nscoord aX, nscoord aY,
|
||||
nscoord aWidth) = 0;
|
||||
|
||||
/**
|
||||
* Copy an image to the RenderingContext
|
||||
* @param aX Horzontal left destination coordinate
|
||||
* @param aY Vertical top of destinatio coordinate
|
||||
*/
|
||||
virtual void DrawImage(nsIImage *aImage, nscoord aX, nscoord aY) = 0;
|
||||
|
||||
/**
|
||||
* Copy an image to the RenderingContext, scaling can occur if width/hieght does not match source
|
||||
* @param aX Horzontal left destination coordinate
|
||||
* @param aY Vertical top of destinatio coordinate
|
||||
* @param aWidth Width of destination,
|
||||
* @param aHeight Height of destination
|
||||
*/
|
||||
virtual void DrawImage(nsIImage *aImage, nscoord aX, nscoord aY,
|
||||
nscoord aWidth, nscoord aHeight) = 0;
|
||||
/**
|
||||
* Copy an image to the RenderingContext, scaling can occur if source/dest rects differ
|
||||
* @param aRect Destination rectangle to copy the image to
|
||||
*/
|
||||
virtual void DrawImage(nsIImage *aImage, const nsRect& aRect) = 0;
|
||||
/**
|
||||
* Copy an image to the RenderingContext, scaling/clipping can occur if source/dest rects differ
|
||||
* @param aSRect Source rectangle to copy from
|
||||
* @param aDRect Destination rectangle to copy the image to
|
||||
*/
|
||||
virtual void DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect)=0;
|
||||
|
||||
/**
|
||||
* Copy offscreen pixelmap to this RenderingContext
|
||||
* @param aBounds Destination rectangle to copy to
|
||||
*/
|
||||
virtual nsresult CopyOffScreenBits(nsRect &aBounds) = 0;
|
||||
};
|
||||
|
||||
//modifiers for text rendering
|
||||
|
||||
#define NS_DRAWSTRING_NORMAL 0x0
|
||||
#define NS_DRAWSTRING_UNDERLINE 0x1
|
||||
#define NS_DRAWSTRING_OVERLINE 0x2
|
||||
#define NS_DRAWSTRING_LINE_THROUGH 0x4
|
||||
|
||||
#endif /* nsIRenderingContext_h___ */
|
||||
87
mozilla/gfx/src/nsImage.h
Normal file
87
mozilla/gfx/src/nsImage.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsImage_h___
|
||||
#define nsImage_h___
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
class nsImage : public nsIImage
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
private:
|
||||
PRInt8 mNumBytesColor; // number of bytes per color
|
||||
PRInt16 mNumPalleteColors; // either 8 or 0
|
||||
PRInt32 mSizeImage; // number of bits, not BITYMAPINFOHEADER
|
||||
PRInt32 mRowBytes; // number of bytes per row
|
||||
PRUint8 *mColorTable; // color table for the bitmap
|
||||
LPBYTE mImageBits; // starting address of DIB bits
|
||||
LPBYTE mAlphaBits; // alpha layer if we made one
|
||||
PRBool mIsOptimized; // Have we turned our DIB into a GDI?
|
||||
nsColorMap *mColorMap; // Redundant with mColorTable, but necessary
|
||||
// for Set/GetColorMap
|
||||
|
||||
#ifdef XP_PC
|
||||
HPALETTE mHPalette;
|
||||
HBITMAP mHBitmap; // the GDI bitmap
|
||||
LPBITMAPINFOHEADER mBHead; // BITMAPINFOHEADER
|
||||
#endif
|
||||
|
||||
public:
|
||||
nsImage();
|
||||
~nsImage();
|
||||
|
||||
|
||||
#ifdef XP_PC
|
||||
virtual BOOL Draw(void *aDrawPort,PRInt32 aX,PRInt32 aY,PRInt32 aWidth,PRInt32 aHeight); // until we implement CreateDibSection
|
||||
virtual PRInt32 GetHeight() { return mBHead->biHeight;}
|
||||
int GetSizeHeader(){return sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD) * mNumPalleteColors;}
|
||||
virtual PRInt32 GetWidth() { return mBHead->biWidth;}
|
||||
BOOL SetSystemPalette(HDC* aHdc);
|
||||
UINT UsePalette(HDC* aHdc, BOOL bBackground = FALSE);
|
||||
#endif
|
||||
|
||||
void CleanUp();
|
||||
virtual PRUint8* GetAlphaBits(){return mAlphaBits;}
|
||||
virtual PRInt32 GetAlphaLineStride() {return mBHead->biWidth;}
|
||||
virtual PRUint8* GetBits() {return mImageBits;}
|
||||
virtual PRInt32 GetLineStride() {return mRowBytes;}
|
||||
int GetSizeImage() {return mSizeImage;}
|
||||
virtual void Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMaskRequirements aMaskRequirements);
|
||||
virtual PRBool IsOptimized() { return mIsOptimized;}
|
||||
BOOL MakePalette();
|
||||
virtual nsresult Optimize(void *aDrawPort);
|
||||
void TestFillBits();
|
||||
|
||||
// methods not complete
|
||||
virtual nsColorMap* GetColorMap();
|
||||
virtual void ImageUpdated(PRUint8 aFlags, nsRect *aUpdateRect);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
private:
|
||||
#ifdef XP_PC
|
||||
void ComputePaletteSize(int aBitCount);
|
||||
void ComputeMetrics();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
293
mozilla/gfx/src/nsImageGroup.cpp
Normal file
293
mozilla/gfx/src/nsImageGroup.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIImageGroup.h"
|
||||
#include "nsIImageManager.h"
|
||||
#include "nsIImageObserver.h"
|
||||
#include "nsIImageRequest.h"
|
||||
#include "nsImageRequest.h"
|
||||
#include "ilIImageRenderer.h"
|
||||
#include "nsImageNet.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsCRT.h"
|
||||
#include "libimg.h"
|
||||
#include "il_util.h"
|
||||
|
||||
static NS_DEFINE_IID(kIImageGroupIID, NS_IIMAGEGROUP_IID);
|
||||
|
||||
static void ns_observer_proc (XP_Observable aSource,
|
||||
XP_ObservableMsg aMsg,
|
||||
void* aMsgData,
|
||||
void* aClosure);
|
||||
|
||||
class ImageGroupImpl : public nsIImageGroup
|
||||
{
|
||||
public:
|
||||
ImageGroupImpl(nsIImageManager *aManager);
|
||||
~ImageGroupImpl();
|
||||
|
||||
nsresult Init(nsIRenderingContext *aRenderingContext);
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
nsCRT::zero(rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual PRBool AddObserver(nsIImageGroupObserver *aObserver);
|
||||
virtual PRBool RemoveObserver(nsIImageGroupObserver *aObserver);
|
||||
|
||||
virtual nsIImageRequest* GetImage(const char* aUrl,
|
||||
nsIImageRequestObserver *aObserver,
|
||||
nscolor aBackgroundColor,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
PRUint32 aFlags);
|
||||
|
||||
virtual void Interrupt(void);
|
||||
|
||||
IL_GroupContext *GetGroupContext() { return mGroupContext; }
|
||||
nsVoidArray *GetObservers() { return mObservers; }
|
||||
|
||||
private:
|
||||
nsIImageManager *mManager;
|
||||
IL_GroupContext *mGroupContext;
|
||||
nsVoidArray *mObservers;
|
||||
nsIRenderingContext *mRenderingContext;
|
||||
IL_ColorSpace *mColorSpace;
|
||||
};
|
||||
|
||||
ImageGroupImpl::ImageGroupImpl(nsIImageManager *aManager)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mManager = aManager;
|
||||
}
|
||||
|
||||
ImageGroupImpl::~ImageGroupImpl()
|
||||
{
|
||||
if (mRenderingContext != nsnull) {
|
||||
NS_RELEASE(mRenderingContext);
|
||||
}
|
||||
|
||||
if (mObservers != nsnull) {
|
||||
PRInt32 i, count = mObservers->Count();
|
||||
nsIImageGroupObserver *observer;
|
||||
for (i = 0; i < count; i++) {
|
||||
observer = (nsIImageGroupObserver *)mObservers->ElementAt(i);
|
||||
if (observer != nsnull) {
|
||||
NS_RELEASE(observer);
|
||||
}
|
||||
}
|
||||
|
||||
delete mObservers;
|
||||
}
|
||||
|
||||
if (mGroupContext != nsnull) {
|
||||
IL_DestroyGroupContext(mGroupContext);
|
||||
}
|
||||
|
||||
if (mColorSpace != nsnull) {
|
||||
IL_ReleaseColorSpace(mColorSpace);
|
||||
}
|
||||
|
||||
if (mManager != nsnull) {
|
||||
NS_RELEASE(mManager);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ImageGroupImpl, kIImageGroupIID)
|
||||
|
||||
nsresult
|
||||
ImageGroupImpl::Init(nsIRenderingContext *aRenderingContext)
|
||||
{
|
||||
ilIImageRenderer *renderer;
|
||||
nsresult result;
|
||||
|
||||
if ((result = NS_NewImageRenderer(&renderer)) != NS_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// XXX Need to create an image renderer
|
||||
mGroupContext = IL_NewGroupContext((void *)aRenderingContext,
|
||||
renderer);
|
||||
|
||||
if (mGroupContext == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mRenderingContext = aRenderingContext;
|
||||
NS_ADDREF(mRenderingContext);
|
||||
|
||||
// XXX Hard coded to be 24-bit. We need to get the right information
|
||||
// from the rendering context (or device context).
|
||||
IL_RGBBits colorRGBBits;
|
||||
|
||||
colorRGBBits.red_shift = 16;
|
||||
colorRGBBits.red_bits = 8;
|
||||
colorRGBBits.green_shift = 8;
|
||||
colorRGBBits.green_bits = 8;
|
||||
colorRGBBits.blue_shift = 0;
|
||||
colorRGBBits.blue_bits = 8;
|
||||
mColorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
|
||||
IL_AddRefToColorSpace(mColorSpace);
|
||||
|
||||
IL_DisplayData displayData;
|
||||
displayData.dither_mode = IL_Auto;
|
||||
displayData.color_space = mColorSpace;
|
||||
displayData.progressive_display = PR_TRUE;
|
||||
IL_SetDisplayMode(mGroupContext,
|
||||
IL_COLOR_SPACE | IL_PROGRESSIVE_DISPLAY | IL_DITHER_MODE,
|
||||
&displayData);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageGroupImpl::AddObserver(nsIImageGroupObserver *aObserver)
|
||||
{
|
||||
if (aObserver == nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (mObservers == nsnull) {
|
||||
mObservers = new nsVoidArray();
|
||||
if (mObservers == nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
IL_AddGroupObserver(mGroupContext, ns_observer_proc, (void *)this);
|
||||
}
|
||||
|
||||
NS_ADDREF(aObserver);
|
||||
mObservers->AppendElement((void *)aObserver);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageGroupImpl::RemoveObserver(nsIImageGroupObserver *aObserver)
|
||||
{
|
||||
PRBool ret;
|
||||
|
||||
if (aObserver == nsnull || mObservers == nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
ret = mObservers->RemoveElement((void *)aObserver);
|
||||
|
||||
if (ret == PR_TRUE) {
|
||||
NS_RELEASE(aObserver);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsIImageRequest*
|
||||
ImageGroupImpl::GetImage(const char* aUrl,
|
||||
nsIImageRequestObserver *aObserver,
|
||||
nscolor aBackgroundColor,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aUrl, "null URL");
|
||||
|
||||
ImageRequestImpl *image_req = new ImageRequestImpl();
|
||||
if (image_req != nsnull) {
|
||||
if (image_req->Init(mGroupContext, aUrl, aObserver, aBackgroundColor,
|
||||
aWidth, aHeight, aFlags) == NS_OK) {
|
||||
NS_ADDREF(image_req);
|
||||
}
|
||||
else {
|
||||
delete image_req;
|
||||
image_req = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return image_req;
|
||||
}
|
||||
|
||||
void
|
||||
ImageGroupImpl::Interrupt(void)
|
||||
{
|
||||
if (mGroupContext != nsnull) {
|
||||
IL_InterruptContext(mGroupContext);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewImageGroup(nsIImageGroup **aInstancePtrResult)
|
||||
{
|
||||
nsresult result;
|
||||
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsIImageManager *manager;
|
||||
if ((result = NS_NewImageManager(&manager)) != NS_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIImageGroup *group = new ImageGroupImpl(manager);
|
||||
if (group == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return group->QueryInterface(kIImageGroupIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
static void ns_observer_proc (XP_Observable aSource,
|
||||
XP_ObservableMsg aMsg,
|
||||
void* aMsgData,
|
||||
void* aClosure)
|
||||
{
|
||||
ImageGroupImpl *image_group = (ImageGroupImpl *)aClosure;
|
||||
nsVoidArray *observer_list = image_group->GetObservers();
|
||||
|
||||
if (observer_list != nsnull) {
|
||||
PRInt32 i, count = observer_list->Count();
|
||||
nsIImageGroupObserver *observer;
|
||||
for (i = 0; i < count; i++) {
|
||||
observer = (nsIImageGroupObserver *)observer_list->ElementAt(i);
|
||||
if (observer != nsnull) {
|
||||
switch (aMsg) {
|
||||
case IL_STARTED_LOADING:
|
||||
observer->Notify(image_group,
|
||||
nsImageGroupNotification_kStartedLoading);
|
||||
break;
|
||||
case IL_ABORTED_LOADING:
|
||||
observer->Notify(image_group,
|
||||
nsImageGroupNotification_kAbortedLoading);
|
||||
case IL_FINISHED_LOADING:
|
||||
observer->Notify(image_group,
|
||||
nsImageGroupNotification_kFinishedLoading);
|
||||
case IL_STARTED_LOOPING:
|
||||
observer->Notify(image_group,
|
||||
nsImageGroupNotification_kStartedLooping);
|
||||
case IL_FINISHED_LOOPING:
|
||||
observer->Notify(image_group,
|
||||
nsImageGroupNotification_kFinishedLooping);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
136
mozilla/gfx/src/nsImageManager.cpp
Normal file
136
mozilla/gfx/src/nsImageManager.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIImageManager.h"
|
||||
#include "libimg.h"
|
||||
#include "il_strm.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsImageNet.h"
|
||||
|
||||
static NS_DEFINE_IID(kIImageManagerIID, NS_IIMAGEMANAGER_IID);
|
||||
|
||||
class ImageManagerImpl : public nsIImageManager {
|
||||
public:
|
||||
static ImageManagerImpl *sTheImageManager;
|
||||
|
||||
ImageManagerImpl();
|
||||
~ImageManagerImpl();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
nsCRT::zero(rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void SetCacheSize(PRInt32 aCacheSize);
|
||||
virtual PRInt32 GetCacheSize(void);
|
||||
virtual PRInt32 ShrinkCache(void);
|
||||
virtual nsImageType GetImageType(const char *buf, PRInt32 length);
|
||||
|
||||
private:
|
||||
ilISystemServices *mSS;
|
||||
};
|
||||
|
||||
ImageManagerImpl* ImageManagerImpl::sTheImageManager = nsnull;
|
||||
|
||||
ImageManagerImpl::ImageManagerImpl()
|
||||
{
|
||||
NS_NewImageSystemServices(&mSS);
|
||||
NS_ADDREF(mSS);
|
||||
IL_Init(mSS);
|
||||
}
|
||||
|
||||
ImageManagerImpl::~ImageManagerImpl()
|
||||
{
|
||||
IL_Shutdown();
|
||||
NS_RELEASE(mSS);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ImageManagerImpl, kIImageManagerIID)
|
||||
|
||||
nsresult
|
||||
ImageManagerImpl::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ImageManagerImpl::SetCacheSize(PRInt32 aCacheSize)
|
||||
{
|
||||
IL_SetCacheSize(aCacheSize);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
ImageManagerImpl::GetCacheSize()
|
||||
{
|
||||
return IL_GetCacheSize();
|
||||
}
|
||||
|
||||
PRInt32
|
||||
ImageManagerImpl::ShrinkCache(void)
|
||||
{
|
||||
return IL_ShrinkCache();
|
||||
}
|
||||
|
||||
nsImageType
|
||||
ImageManagerImpl::GetImageType(const char *buf, PRInt32 length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
NS_PRECONDITION(nsnull != buf, "null ptr");
|
||||
ret = IL_Type(buf, length);
|
||||
|
||||
switch(ret) {
|
||||
case(IL_GIF):
|
||||
return nsImageType_kGIF;
|
||||
case(IL_XBM):
|
||||
return nsImageType_kXBM;
|
||||
case(IL_JPEG):
|
||||
return nsImageType_kJPEG;
|
||||
case(IL_PPM):
|
||||
return nsImageType_kPPM;
|
||||
case(IL_PNG):
|
||||
return nsImageType_kPNG;
|
||||
default:
|
||||
return nsImageType_kUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
NS_GFX nsresult
|
||||
NS_NewImageManager(nsIImageManager **aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (ImageManagerImpl::sTheImageManager == nsnull) {
|
||||
ImageManagerImpl::sTheImageManager = new ImageManagerImpl();
|
||||
}
|
||||
|
||||
if (ImageManagerImpl::sTheImageManager == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return ImageManagerImpl::sTheImageManager->QueryInterface(kIImageManagerIID,
|
||||
(void **) aInstancePtrResult);
|
||||
}
|
||||
31
mozilla/gfx/src/nsImageNet.h
Normal file
31
mozilla/gfx/src/nsImageNet.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "ilINetContext.h"
|
||||
#include "ilIURL.h"
|
||||
#include "ilIImageRenderer.h"
|
||||
#include "ilISystemServices.h"
|
||||
#include "nscore.h"
|
||||
|
||||
extern NS_GFX nsresult NS_NewImageNetContext(ilINetContext **aInstancePtrResult);
|
||||
extern NS_GFX nsresult NS_NewImageURL(ilIURL **aInstancePtrResult,
|
||||
const char *aURL);
|
||||
|
||||
extern NS_GFX nsresult NS_NewImageRenderer(ilIImageRenderer **aInstancePtrResult);
|
||||
|
||||
extern NS_GFX nsresult NS_NewImageSystemServices(ilISystemServices **aInstancePtrResult);
|
||||
350
mozilla/gfx/src/nsImageNetContext.cpp
Normal file
350
mozilla/gfx/src/nsImageNetContext.cpp
Normal file
@@ -0,0 +1,350 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "libimg.h"
|
||||
#include "nsImageNet.h"
|
||||
#include "ilINetContext.h"
|
||||
#include "ilIURL.h"
|
||||
#include "ilINetReader.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
#include "il_strm.h"
|
||||
|
||||
static NS_DEFINE_IID(kIImageNetContextIID, IL_INETCONTEXT_IID);
|
||||
static NS_DEFINE_IID(kIURLIID, NS_IURL_IID);
|
||||
|
||||
class ImageNetContextImpl : public ilINetContext {
|
||||
public:
|
||||
ImageNetContextImpl(NET_ReloadMethod aReloadPolicy);
|
||||
~ImageNetContextImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual ilINetContext* Clone();
|
||||
|
||||
virtual NET_ReloadMethod GetReloadPolicy();
|
||||
|
||||
virtual void AddReferer(ilIURL *aUrl);
|
||||
|
||||
virtual void Interrupt();
|
||||
|
||||
virtual ilIURL* CreateURL(const char *aUrl,
|
||||
NET_ReloadMethod aReloadMethod);
|
||||
|
||||
virtual PRBool IsLocalFileURL(char *aAddress);
|
||||
|
||||
virtual PRBool IsURLInMemCache(ilIURL *aUrl);
|
||||
|
||||
virtual PRBool IsURLInDiskCache(ilIURL *aUrl);
|
||||
|
||||
virtual int GetURL (ilIURL * aUrl, NET_ReloadMethod aLoadMethod,
|
||||
ilINetReader *aReader);
|
||||
|
||||
nsITimer *mTimer;
|
||||
nsVoidArray *mRequests;
|
||||
NET_ReloadMethod mReloadPolicy;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ilIURL *mURL;
|
||||
nsIInputStream *mStream;
|
||||
} NetRequestStr;
|
||||
|
||||
ImageNetContextImpl::ImageNetContextImpl(NET_ReloadMethod aReloadPolicy)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mTimer = nsnull;
|
||||
mRequests = nsnull;
|
||||
mReloadPolicy = aReloadPolicy;
|
||||
}
|
||||
|
||||
ImageNetContextImpl::~ImageNetContextImpl()
|
||||
{
|
||||
if (mTimer != nsnull) {
|
||||
mTimer->Cancel();
|
||||
NS_RELEASE(mTimer);
|
||||
}
|
||||
|
||||
if (mRequests != nsnull) {
|
||||
int i, count = mRequests->Count();
|
||||
for (i=0; i < count; i++) {
|
||||
NetRequestStr *req = (NetRequestStr *)mRequests->ElementAt(i);
|
||||
|
||||
if (req->mURL != nsnull) {
|
||||
NS_RELEASE(req->mURL);
|
||||
}
|
||||
|
||||
if (req->mStream != nsnull) {
|
||||
NS_RELEASE(req->mStream);
|
||||
}
|
||||
|
||||
PR_DELETE(req);
|
||||
}
|
||||
delete mRequests;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ImageNetContextImpl, kIImageNetContextIID)
|
||||
|
||||
ilINetContext*
|
||||
ImageNetContextImpl::Clone()
|
||||
{
|
||||
ilINetContext *cx;
|
||||
|
||||
if (NS_NewImageNetContext(&cx) == NS_OK) {
|
||||
return cx;
|
||||
}
|
||||
else {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NET_ReloadMethod
|
||||
ImageNetContextImpl::GetReloadPolicy()
|
||||
{
|
||||
return mReloadPolicy;
|
||||
}
|
||||
|
||||
void
|
||||
ImageNetContextImpl::AddReferer(ilIURL *aUrl)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ImageNetContextImpl::Interrupt()
|
||||
{
|
||||
}
|
||||
|
||||
ilIURL*
|
||||
ImageNetContextImpl::CreateURL(const char *aURL,
|
||||
NET_ReloadMethod aReloadMethod)
|
||||
{
|
||||
ilIURL *url;
|
||||
|
||||
if (NS_NewImageURL(&url, aURL) == NS_OK) {
|
||||
return url;
|
||||
}
|
||||
else {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageNetContextImpl::IsLocalFileURL(char *aAddress)
|
||||
{
|
||||
if (PL_strncasecmp(aAddress, "file:", 5) == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageNetContextImpl::IsURLInMemCache(ilIURL *aUrl)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageNetContextImpl::IsURLInDiskCache(ilIURL *aUrl)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#define IMAGE_BUF_SIZE 4096
|
||||
|
||||
void
|
||||
LoadURLs (nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
ImageNetContextImpl *cx = (ImageNetContextImpl *)aClosure;
|
||||
|
||||
NS_RELEASE(aTimer);
|
||||
cx->mTimer = nsnull;
|
||||
|
||||
if (cx->mRequests) {
|
||||
int i, count = cx->mRequests->Count();
|
||||
|
||||
char *buffer = (char *)PR_MALLOC(IMAGE_BUF_SIZE);
|
||||
if (buffer == nsnull) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < count; i++) {
|
||||
NetRequestStr *req = (NetRequestStr *)cx->mRequests->ElementAt(i);
|
||||
ilIURL *ilurl = req->mURL;
|
||||
PRInt32 status = 0;
|
||||
PRBool reschedule = PR_FALSE;
|
||||
|
||||
if (ilurl != nsnull) {
|
||||
nsIURL *nsurl;
|
||||
ilINetReader *reader = ilurl->GetReader();
|
||||
nsIInputStream *stream = nsnull;
|
||||
|
||||
if (req->mStream != nsnull) {
|
||||
stream = req->mStream;
|
||||
}
|
||||
else {
|
||||
if (reader->StreamCreated(ilurl, IL_UNKNOWN) == PR_TRUE &&
|
||||
ilurl->QueryInterface(kIURLIID, (void **)&nsurl) == NS_OK) {
|
||||
PRInt32 ec;
|
||||
stream = nsurl->Open(&ec);
|
||||
if (nsnull == stream) {
|
||||
reader->StreamAbort(-1);
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
reader->StreamAbort(-1);
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
PRInt32 err = 0, nb;
|
||||
PRBool first = (PRBool)(req->mStream == nsnull);
|
||||
do {
|
||||
if (reader->WriteReady() <= 0) {
|
||||
req->mStream = stream;
|
||||
reschedule = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
err = 0;
|
||||
nb = stream->Read(&err, buffer, 0,
|
||||
IMAGE_BUF_SIZE);
|
||||
if (err != 0 && err != NS_INPUTSTREAM_EOF) {
|
||||
break;
|
||||
}
|
||||
if (first == PR_TRUE) {
|
||||
PRInt32 ilErr;
|
||||
|
||||
ilErr = reader->FirstWrite((const unsigned char *)buffer, nb);
|
||||
first = PR_FALSE;
|
||||
/*
|
||||
* If FirstWrite(...) fails then the image type
|
||||
* cannot be determined and the il_container
|
||||
* stream functions have not been initialized!
|
||||
*/
|
||||
if (ilErr != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reader->Write((const unsigned char *)buffer, nb);
|
||||
} while (err != NS_INPUTSTREAM_EOF);
|
||||
|
||||
if (err == NS_INPUTSTREAM_EOF) {
|
||||
reader->StreamComplete(PR_FALSE);
|
||||
}
|
||||
else if (err != 0) {
|
||||
reader->StreamAbort(-1);
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reschedule) {
|
||||
if (stream != nsnull) {
|
||||
NS_RELEASE(stream);
|
||||
}
|
||||
req->mStream = nsnull;
|
||||
reader->NetRequestDone(ilurl, status);
|
||||
NS_RELEASE(reader);
|
||||
NS_RELEASE(ilurl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=count-1; i >= 0; i--) {
|
||||
NetRequestStr *req = (NetRequestStr *)cx->mRequests->ElementAt(i);
|
||||
|
||||
if (req->mStream == nsnull) {
|
||||
cx->mRequests->RemoveElementAt(i);
|
||||
PR_DELETE(req);
|
||||
}
|
||||
else if (cx->mTimer == nsnull) {
|
||||
if (NS_NewTimer(&cx->mTimer) == NS_OK) {
|
||||
cx->mTimer->Init(LoadURLs, (void *)cx, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_FREEIF(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ImageNetContextImpl::GetURL (ilIURL * aURL,
|
||||
NET_ReloadMethod aLoadMethod,
|
||||
ilINetReader *aReader)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aURL, "null URL");
|
||||
NS_PRECONDITION(nsnull != aReader, "null reader");
|
||||
if (aURL == nsnull || aReader == nsnull) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mRequests == nsnull) {
|
||||
mRequests = new nsVoidArray();
|
||||
if (mRequests == nsnull) {
|
||||
// XXX Should still call exit function
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTimer == nsnull) {
|
||||
if (NS_NewTimer(&mTimer) != NS_OK) {
|
||||
// XXX Should still call exit function
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mTimer->Init(LoadURLs, (void *)this, 0) != NS_OK) {
|
||||
// XXX Should still call exit function
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
aURL->SetReader(aReader);
|
||||
|
||||
NetRequestStr *req = PR_NEWZAP(NetRequestStr);
|
||||
req->mURL = aURL;
|
||||
NS_ADDREF(aURL);
|
||||
|
||||
mRequests->AppendElement((void *)req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewImageNetContext(ilINetContext **aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
ilINetContext *cx = new ImageNetContextImpl(NET_NORMAL_RELOAD);
|
||||
if (cx == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return cx->QueryInterface(kIImageNetContextIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
282
mozilla/gfx/src/nsImageRenderer.cpp
Normal file
282
mozilla/gfx/src/nsImageRenderer.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "libimg.h"
|
||||
#include "ilIImageRenderer.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "ni_pixmp.h"
|
||||
#include "il_util.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
|
||||
static NS_DEFINE_IID(kIImageRendererIID, IL_IIMAGERENDERER_IID);
|
||||
|
||||
class ImageRendererImpl : public ilIImageRenderer {
|
||||
public:
|
||||
static IL_ColorSpace *sPseudoColorSpace;
|
||||
|
||||
ImageRendererImpl();
|
||||
~ImageRendererImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void NewPixmap(void* aDisplayContext,
|
||||
PRInt32 aWidth, PRInt32 aHeight,
|
||||
IL_Pixmap* aImage, IL_Pixmap* aMask);
|
||||
|
||||
virtual void UpdatePixmap(void* aDisplayContext,
|
||||
IL_Pixmap* aImage,
|
||||
PRInt32 aXOffset, PRInt32 aYOffset,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
virtual void ControlPixmapBits(void* aDisplayContext,
|
||||
IL_Pixmap* aImage, PRUint32 aControlMsg);
|
||||
|
||||
virtual void DestroyPixmap(void* aDisplayContext, IL_Pixmap* aImage);
|
||||
|
||||
virtual void DisplayPixmap(void* aDisplayContext,
|
||||
IL_Pixmap* aImage, IL_Pixmap* aMask,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aXOffset, PRInt32 aYOffset,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
virtual void DisplayIcon(void* aDisplayContext,
|
||||
PRInt32 aX, PRInt32 aY, PRUint32 aIconNumber);
|
||||
|
||||
virtual void GetIconDimensions(void* aDisplayContext,
|
||||
PRInt32 *aWidthPtr, PRInt32 *aHeightPtr,
|
||||
PRUint32 aIconNumber);
|
||||
};
|
||||
|
||||
IL_ColorSpace *ImageRendererImpl::sPseudoColorSpace = nsnull;
|
||||
|
||||
ImageRendererImpl::ImageRendererImpl()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
ImageRendererImpl::~ImageRendererImpl()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ImageRendererImpl, kIImageRendererIID)
|
||||
|
||||
|
||||
void
|
||||
ImageRendererImpl::NewPixmap(void* aDisplayContext,
|
||||
PRInt32 aWidth, PRInt32 aHeight,
|
||||
IL_Pixmap* aImage, IL_Pixmap* aMask)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
nsIImage *img;
|
||||
nsresult rv;
|
||||
|
||||
static NS_DEFINE_IID(kImageCID, NS_IMAGE_CID);
|
||||
static NS_DEFINE_IID(kImageIID, NS_IIMAGE_IID);
|
||||
|
||||
rv = NSRepository::CreateInstance(kImageCID, nsnull, kImageIID, (void **)&img);
|
||||
|
||||
if (NS_OK != rv)
|
||||
return;
|
||||
|
||||
PRInt32 depth;
|
||||
if (aImage->header.color_space->pixmap_depth == 8) {
|
||||
depth = 8;
|
||||
}
|
||||
else {
|
||||
depth = 24;
|
||||
}
|
||||
|
||||
img->Init(aWidth, aHeight, depth,
|
||||
(aMask == nsnull) ? nsMaskRequirements_kNoMask :
|
||||
nsMaskRequirements_kNeeds1Bit);
|
||||
|
||||
aImage->bits = img->GetBits();
|
||||
aImage->client_data = img;
|
||||
NS_ADDREF(img);
|
||||
aImage->header.width = aWidth;
|
||||
aImage->header.height = aHeight;
|
||||
aImage->header.widthBytes = img->GetLineStride();
|
||||
|
||||
if (aMask) {
|
||||
aMask->bits = img->GetAlphaBits();
|
||||
aMask->client_data = img;
|
||||
aMask->header.width = aWidth;
|
||||
aMask->header.height = aHeight;
|
||||
}
|
||||
|
||||
if (aImage->header.color_space->pixmap_depth == 8) {
|
||||
IL_ColorMap *cmap;
|
||||
if (sPseudoColorSpace == nsnull) {
|
||||
cmap = IL_NewCubeColorMap(nsnull, 0, 216);
|
||||
|
||||
if (cmap != nsnull) {
|
||||
sPseudoColorSpace = IL_CreatePseudoColorSpace(cmap, 8, 8);
|
||||
|
||||
if (sPseudoColorSpace == nsnull) {
|
||||
IL_DestroyColorMap(cmap);
|
||||
|
||||
// XXX We should do something here
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// XXX We should do something here
|
||||
return;
|
||||
}
|
||||
}
|
||||
IL_AddRefToColorSpace(sPseudoColorSpace);
|
||||
IL_ReleaseColorSpace(aImage->header.color_space);
|
||||
aImage->header.color_space = sPseudoColorSpace;
|
||||
|
||||
cmap = &sPseudoColorSpace->cmap;
|
||||
nsColorMap *nscmap = img->GetColorMap();
|
||||
PRUint8 *mapptr = nscmap->Index;
|
||||
int i;
|
||||
|
||||
for (i=0; i < cmap->num_colors; i++) {
|
||||
*mapptr++ = cmap->map[i].red;
|
||||
*mapptr++ = cmap->map[i].green;
|
||||
*mapptr++ = cmap->map[i].blue;
|
||||
}
|
||||
|
||||
nsIDeviceContext *dx = rc->GetDeviceContext();
|
||||
img->ImageUpdated(dx, nsImageUpdateFlags_kColorMapChanged, nsnull);
|
||||
NS_IF_RELEASE(dx);
|
||||
|
||||
if (aImage->header.transparent_pixel) {
|
||||
PRUint8 red, green, blue;
|
||||
PRUint8 *lookup_table = (PRUint8 *)aImage->header.color_space->cmap.table;
|
||||
red = aImage->header.transparent_pixel->red;
|
||||
green = aImage->header.transparent_pixel->green;
|
||||
blue = aImage->header.transparent_pixel->blue;
|
||||
aImage->header.transparent_pixel->index =
|
||||
lookup_table[((red >> 3) << 10) |
|
||||
((green >> 3) << 5) |
|
||||
(blue >> 3)];
|
||||
}
|
||||
}
|
||||
else {
|
||||
IL_RGBBits colorRGBBits;
|
||||
IL_ColorSpace *colorSpace;
|
||||
|
||||
colorRGBBits.red_shift = 16;
|
||||
colorRGBBits.red_bits = 8;
|
||||
colorRGBBits.green_shift = 8;
|
||||
colorRGBBits.green_bits = 8;
|
||||
colorRGBBits.blue_shift = 0;
|
||||
colorRGBBits.blue_bits = 8;
|
||||
colorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
|
||||
IL_AddRefToColorSpace(colorSpace);
|
||||
IL_ReleaseColorSpace(aImage->header.color_space);
|
||||
aImage->header.color_space = colorSpace;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageRendererImpl::UpdatePixmap(void* aDisplayContext,
|
||||
IL_Pixmap* aImage,
|
||||
PRInt32 aXOffset, PRInt32 aYOffset,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
nsIImage *img = (nsIImage *)aImage->client_data;
|
||||
nsIDeviceContext *dx = rc->GetDeviceContext();
|
||||
nsRect drect(aXOffset, aYOffset, aWidth, aHeight);
|
||||
|
||||
img->ImageUpdated(dx, nsImageUpdateFlags_kBitsChanged, &drect);
|
||||
|
||||
NS_IF_RELEASE(dx);
|
||||
}
|
||||
|
||||
void
|
||||
ImageRendererImpl::ControlPixmapBits(void* aDisplayContext,
|
||||
IL_Pixmap* aImage, PRUint32 aControlMsg)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
nsIImage *img = (nsIImage *)aImage->client_data;
|
||||
|
||||
if (aControlMsg == IL_RELEASE_BITS) {
|
||||
nsIDeviceContext *dx = rc->GetDeviceContext();
|
||||
if (nsnull != dx) {
|
||||
nsDrawingSurface surf = dx->GetDrawingSurface(*rc);
|
||||
if (nsnull != surf)
|
||||
img->Optimize(surf);
|
||||
NS_RELEASE(dx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageRendererImpl::DestroyPixmap(void* aDisplayContext, IL_Pixmap* aImage)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
nsIImage *img = (nsIImage *)aImage->client_data;
|
||||
|
||||
aImage->client_data = nsnull;
|
||||
if (img) {
|
||||
NS_RELEASE(img);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageRendererImpl::DisplayPixmap(void* aDisplayContext,
|
||||
IL_Pixmap* aImage, IL_Pixmap* aMask,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aXOffset, PRInt32 aYOffset,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
nsIImage *img = (nsIImage *)aImage->client_data;
|
||||
|
||||
// XXX Need better version of DrawImage
|
||||
rc->DrawImage(img, aX, aY);
|
||||
}
|
||||
|
||||
void
|
||||
ImageRendererImpl::DisplayIcon(void* aDisplayContext,
|
||||
PRInt32 aX, PRInt32 aY, PRUint32 aIconNumber)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
}
|
||||
|
||||
void
|
||||
ImageRendererImpl::GetIconDimensions(void* aDisplayContext,
|
||||
PRInt32 *aWidthPtr, PRInt32 *aHeightPtr,
|
||||
PRUint32 aIconNumber)
|
||||
{
|
||||
nsIRenderingContext *rc = (nsIRenderingContext *)aDisplayContext;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewImageRenderer(ilIImageRenderer **aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
ilIImageRenderer *renderer = new ImageRendererImpl();
|
||||
if (renderer == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return renderer->QueryInterface(kIImageRendererIID,
|
||||
(void **) aInstancePtrResult);
|
||||
}
|
||||
326
mozilla/gfx/src/nsImageRequest.cpp
Normal file
326
mozilla/gfx/src/nsImageRequest.cpp
Normal file
@@ -0,0 +1,326 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsImageRequest.h"
|
||||
#include "nsIImageGroup.h"
|
||||
#include "nsIImageObserver.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsRect.h"
|
||||
#include "ilINetContext.h"
|
||||
#include "nsImageNet.h"
|
||||
|
||||
static NS_DEFINE_IID(kIImageRequestIID, NS_IIMAGEREQUEST_IID);
|
||||
|
||||
static void ns_observer_proc (XP_Observable aSource,
|
||||
XP_ObservableMsg aMsg,
|
||||
void* aMsgData,
|
||||
void* aClosure);
|
||||
|
||||
ImageRequestImpl::ImageRequestImpl()
|
||||
{
|
||||
}
|
||||
|
||||
ImageRequestImpl::~ImageRequestImpl()
|
||||
{
|
||||
// Observer list destroyed by the image library
|
||||
}
|
||||
|
||||
nsresult
|
||||
ImageRequestImpl::Init(IL_GroupContext *aGroupContext,
|
||||
const char* aUrl,
|
||||
nsIImageRequestObserver *aObserver,
|
||||
nscolor aBackgroundColor,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aGroupContext, "null group context");
|
||||
NS_PRECONDITION(nsnull != aUrl, "null URL");
|
||||
|
||||
NS_Error status;
|
||||
IL_IRGB bgcolor;
|
||||
PRUint32 flags;
|
||||
nsresult result;
|
||||
|
||||
mGroupContext = aGroupContext;
|
||||
|
||||
if (AddObserver(aObserver) == PR_FALSE) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
status = XP_NewObserverList(NULL, &mXPObserver);
|
||||
if (status < 0) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
status = XP_AddObserver(mXPObserver, ns_observer_proc, (void *)this);
|
||||
if (status < 0) {
|
||||
XP_DisposeObserverList(mXPObserver);
|
||||
mXPObserver = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
bgcolor.red = NS_GET_R(aBackgroundColor);
|
||||
bgcolor.green = NS_GET_G(aBackgroundColor);
|
||||
bgcolor.blue = NS_GET_B(aBackgroundColor);
|
||||
|
||||
flags = ((aFlags & IL_HIGH_PRIORITY) ? nsImageLoadFlags_kHighPriority : 0) |
|
||||
((aFlags & IL_STICKY) ? nsImageLoadFlags_kSticky : 0) |
|
||||
((aFlags & IL_BYPASS_CACHE) ? nsImageLoadFlags_kBypassCache : 0) |
|
||||
((aFlags & IL_ONLY_FROM_CACHE) ? nsImageLoadFlags_kOnlyFromCache : 0);
|
||||
|
||||
ilINetContext *net_cx;
|
||||
|
||||
if ((result = NS_NewImageNetContext(&net_cx)) != NS_OK) {
|
||||
XP_DisposeObserverList(mXPObserver);
|
||||
mXPObserver = nsnull;
|
||||
return result;
|
||||
}
|
||||
|
||||
mImageReq = IL_GetImage(aUrl, aGroupContext, mXPObserver, &bgcolor,
|
||||
aWidth, aHeight, flags, (void *)net_cx);
|
||||
|
||||
if (mImageReq == nsnull) {
|
||||
XP_DisposeObserverList(mXPObserver);
|
||||
mXPObserver = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(ImageRequestImpl)
|
||||
NS_IMPL_QUERY_INTERFACE(ImageRequestImpl, kIImageRequestIID)
|
||||
|
||||
nsrefcnt ImageRequestImpl::Release(void)
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
IL_DestroyImage(mImageReq);
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsIImage*
|
||||
ImageRequestImpl::GetImage()
|
||||
{
|
||||
if (mImageReq != nsnull) {
|
||||
IL_Pixmap *pixmap = IL_GetImagePixmap(mImageReq);
|
||||
|
||||
if (pixmap != nsnull) {
|
||||
nsIImage *image = (nsIImage *)pixmap->client_data;
|
||||
|
||||
if (image != nsnull) {
|
||||
NS_ADDREF(image);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
ImageRequestImpl::GetNaturalDimensions(PRUint32 *aWidth, PRUint32 *aHeight)
|
||||
{
|
||||
if (mImageReq != nsnull) {
|
||||
IL_GetNaturalDimensions(mImageReq, (int *)aWidth, (int *)aHeight);
|
||||
}
|
||||
else {
|
||||
*aWidth = 0;
|
||||
*aHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageRequestImpl::AddObserver(nsIImageRequestObserver *aObserver)
|
||||
{
|
||||
if (aObserver == nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (mObservers == nsnull) {
|
||||
mObservers = new nsVoidArray();
|
||||
if (mObservers == nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(aObserver);
|
||||
mObservers->AppendElement((void *)aObserver);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageRequestImpl::RemoveObserver(nsIImageRequestObserver *aObserver)
|
||||
{
|
||||
PRBool ret;
|
||||
|
||||
if (aObserver == nsnull || mObservers == nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
ret = mObservers->RemoveElement((void *)aObserver);
|
||||
|
||||
if (ret == PR_TRUE) {
|
||||
NS_RELEASE(aObserver);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
ImageRequestImpl::Interrupt()
|
||||
{
|
||||
if (mImageReq != nsnull) {
|
||||
IL_InterruptRequest(mImageReq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ns_observer_proc (XP_Observable aSource,
|
||||
XP_ObservableMsg aMsg,
|
||||
void* aMsgData,
|
||||
void* aClosure)
|
||||
{
|
||||
ImageRequestImpl *image_request = (ImageRequestImpl *)aClosure;
|
||||
IL_MessageData *message_data = (IL_MessageData *)aMsgData;
|
||||
nsVoidArray *observer_list = image_request->GetObservers();
|
||||
nsIImage *image = nsnull;
|
||||
// IL_ImageReq *il_image_req = image_request->GetImageRequest();
|
||||
IL_ImageReq *il_image_req = (IL_ImageReq *)aSource;
|
||||
|
||||
if (il_image_req != nsnull) {
|
||||
IL_Pixmap *pixmap = IL_GetImagePixmap(il_image_req);
|
||||
|
||||
if (pixmap != nsnull) {
|
||||
image = (nsIImage *)pixmap->client_data;
|
||||
}
|
||||
}
|
||||
|
||||
if (observer_list != nsnull) {
|
||||
PRInt32 i, count = observer_list->Count();
|
||||
nsIImageRequestObserver *observer;
|
||||
for (i = 0; i < count; i++) {
|
||||
observer = (nsIImageRequestObserver *)observer_list->ElementAt(i);
|
||||
if (observer != nsnull) {
|
||||
switch (aMsg) {
|
||||
case IL_START_URL:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kStartURL, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_DESCRIPTION:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kDescription, 0, 0,
|
||||
message_data->description);
|
||||
break;
|
||||
case IL_DIMENSIONS:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kDimensions,
|
||||
(PRInt32)message_data->width,
|
||||
(PRInt32)message_data->height,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_IS_TRANSPARENT:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kIsTransparent, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_PIXMAP_UPDATE:
|
||||
{
|
||||
nsRect rect(message_data->update_rect.x_origin,
|
||||
message_data->update_rect.y_origin,
|
||||
message_data->update_rect.width,
|
||||
message_data->update_rect.height);
|
||||
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kPixmapUpdate, 0, 0,
|
||||
&rect);
|
||||
}
|
||||
break;
|
||||
case IL_FRAME_COMPLETE:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kFrameComplete, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_PROGRESS:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kProgress,
|
||||
message_data->percent_progress, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_IMAGE_COMPLETE:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kImageComplete, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_STOP_URL:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kStopURL, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_IMAGE_DESTROYED:
|
||||
image_request->SetImageRequest(nsnull);
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kImageDestroyed, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_ABORTED:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kAborted, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_INTERNAL_IMAGE:
|
||||
observer->Notify(image_request,
|
||||
image, nsImageNotification_kInternalImage, 0, 0,
|
||||
nsnull);
|
||||
break;
|
||||
case IL_NOT_IN_CACHE:
|
||||
observer->NotifyError(image_request,
|
||||
nsImageError_kNotInCache);
|
||||
break;
|
||||
case IL_ERROR_NO_DATA:
|
||||
observer->NotifyError(image_request,
|
||||
nsImageError_kNoData);
|
||||
break;
|
||||
case IL_ERROR_IMAGE_DATA_CORRUPT:
|
||||
observer->NotifyError(image_request,
|
||||
nsImageError_kImageDataCorrupt);
|
||||
break;
|
||||
case IL_ERROR_IMAGE_DATA_TRUNCATED:
|
||||
observer->NotifyError(image_request,
|
||||
nsImageError_kImageDataTruncated);
|
||||
break;
|
||||
case IL_ERROR_IMAGE_DATA_ILLEGAL:
|
||||
observer->NotifyError(image_request,
|
||||
nsImageError_kImageDataIllegal);
|
||||
break;
|
||||
case IL_ERROR_INTERNAL:
|
||||
observer->NotifyError(image_request,
|
||||
nsImageError_kInternalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
74
mozilla/gfx/src/nsImageRequest.h
Normal file
74
mozilla/gfx/src/nsImageRequest.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsImageRequest_h___
|
||||
#define nsImageRequest_h___
|
||||
|
||||
#include "nsIImageRequest.h"
|
||||
#include "libimg.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsColor.h"
|
||||
|
||||
class nsVoidArray;
|
||||
class nsIImageRequestObserver;
|
||||
|
||||
class ImageRequestImpl : public nsIImageRequest {
|
||||
public:
|
||||
ImageRequestImpl();
|
||||
~ImageRequestImpl();
|
||||
|
||||
nsresult Init(IL_GroupContext *aGroupContext, const char* aUrl,
|
||||
nsIImageRequestObserver *aObserver,
|
||||
nscolor aBackgroundColor,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
PRUint32 aFlags);
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
nsCRT::zero(rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// Get the image associated with the request.
|
||||
virtual nsIImage* GetImage();
|
||||
|
||||
// Return the natural dimensions of the image. Returns 0,0
|
||||
//if the dimensions are unknown.
|
||||
virtual void GetNaturalDimensions(PRUint32 *aWidth, PRUint32 *aHeight);
|
||||
|
||||
// Add and remove observers to listen in on image loading notifications
|
||||
virtual PRBool AddObserver(nsIImageRequestObserver *aObserver);
|
||||
virtual PRBool RemoveObserver(nsIImageRequestObserver *aObserver);
|
||||
|
||||
// Interrupt loading of just this image.
|
||||
virtual void Interrupt();
|
||||
|
||||
IL_ImageReq *GetImageRequest() { return mImageReq; }
|
||||
void SetImageRequest(IL_ImageReq *aImageReq) { mImageReq = aImageReq; }
|
||||
nsVoidArray *GetObservers() { return mObservers; }
|
||||
|
||||
private:
|
||||
IL_ImageReq *mImageReq;
|
||||
IL_GroupContext *mGroupContext;
|
||||
nsVoidArray *mObservers;
|
||||
XP_ObserverList mXPObserver;
|
||||
};
|
||||
|
||||
#endif
|
||||
134
mozilla/gfx/src/nsImageSystemServices.cpp
Normal file
134
mozilla/gfx/src/nsImageSystemServices.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "ilISystemServices.h"
|
||||
#include "nsITimer.h"
|
||||
#include "prtypes.h"
|
||||
#include "prmem.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
static NS_DEFINE_IID(kISystemServicesIID, IL_ISYSTEMSERVICES_IID);
|
||||
|
||||
class ImageSystemServicesImpl : public ilISystemServices {
|
||||
public:
|
||||
static ImageSystemServicesImpl *sSS;
|
||||
|
||||
ImageSystemServicesImpl();
|
||||
~ImageSystemServicesImpl();
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
nsCRT::zero(rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void * SetTimeout(ilTimeoutCallbackFunction aFunc,
|
||||
void * aClosure, PRUint32 aMsecs);
|
||||
|
||||
virtual void ClearTimeout(void *aTimerID);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ilTimeoutCallbackFunction mFunc;
|
||||
void *mClosure;
|
||||
} TimerClosure;
|
||||
|
||||
ImageSystemServicesImpl* ImageSystemServicesImpl::sSS = nsnull;
|
||||
|
||||
ImageSystemServicesImpl::ImageSystemServicesImpl()
|
||||
{
|
||||
}
|
||||
|
||||
ImageSystemServicesImpl::~ImageSystemServicesImpl()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ImageSystemServicesImpl, kISystemServicesIID)
|
||||
|
||||
void
|
||||
timer_callback (nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
TimerClosure *tc = (TimerClosure *)aClosure;
|
||||
|
||||
(*tc->mFunc)(tc->mClosure);
|
||||
|
||||
NS_RELEASE(aTimer);
|
||||
PR_DELETE(tc);
|
||||
}
|
||||
|
||||
void *
|
||||
ImageSystemServicesImpl::SetTimeout(ilTimeoutCallbackFunction aFunc,
|
||||
void * aClosure, PRUint32 aMsecs)
|
||||
{
|
||||
nsITimer *timer;
|
||||
TimerClosure *tc;
|
||||
|
||||
if (NS_NewTimer(&timer) != NS_OK) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
tc = (TimerClosure *)PR_NEWZAP(TimerClosure);
|
||||
if (tc == nsnull) {
|
||||
NS_RELEASE(timer);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
tc->mFunc = aFunc;
|
||||
tc->mClosure = aClosure;
|
||||
|
||||
if (timer->Init(timer_callback, (void *)tc, aMsecs) != NS_OK) {
|
||||
NS_RELEASE(timer);
|
||||
PR_DELETE(tc);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_ADDREF(timer);
|
||||
|
||||
return (void *)timer;
|
||||
}
|
||||
|
||||
void
|
||||
ImageSystemServicesImpl::ClearTimeout(void *aTimerID)
|
||||
{
|
||||
nsITimer *timer = (nsITimer *)aTimerID;
|
||||
|
||||
timer->Cancel();
|
||||
NS_RELEASE(timer);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewImageSystemServices(ilISystemServices **aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (ImageSystemServicesImpl::sSS == nsnull) {
|
||||
ImageSystemServicesImpl::sSS = new ImageSystemServicesImpl();
|
||||
}
|
||||
|
||||
if (ImageSystemServicesImpl::sSS == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return ImageSystemServicesImpl::sSS->QueryInterface(kISystemServicesIID,
|
||||
(void **) aInstancePtrResult);
|
||||
}
|
||||
179
mozilla/gfx/src/nsImageURL.cpp
Normal file
179
mozilla/gfx/src/nsImageURL.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "libimg.h"
|
||||
#include "nsImageNet.h"
|
||||
#include "ilINetContext.h"
|
||||
#include "ilINetReader.h"
|
||||
#include "ilIURL.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsString.h"
|
||||
#include "il_strm.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kIImageURLIID, IL_IURL_IID);
|
||||
|
||||
class ImageURLImpl : public ilIURL {
|
||||
public:
|
||||
ImageURLImpl(const char *aURL);
|
||||
~ImageURLImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void SetReader(ilINetReader *aReader);
|
||||
|
||||
virtual ilINetReader *GetReader();
|
||||
|
||||
virtual int GetContentLength();
|
||||
|
||||
virtual const char* GetAddress();
|
||||
|
||||
virtual time_t GetExpires();
|
||||
|
||||
virtual void SetBackgroundLoad(PRBool aBgload);
|
||||
|
||||
private:
|
||||
nsIURL *mURL;
|
||||
ilINetReader *mReader;
|
||||
};
|
||||
|
||||
ImageURLImpl::ImageURLImpl(const char *aURL)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_NewURL(&mURL, aURL);
|
||||
mReader = nsnull;
|
||||
}
|
||||
|
||||
ImageURLImpl::~ImageURLImpl()
|
||||
{
|
||||
if (mURL != nsnull) {
|
||||
NS_RELEASE(mURL);
|
||||
}
|
||||
|
||||
if (mReader != nsnull) {
|
||||
NS_RELEASE(mReader);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
ImageURLImpl::QueryInterface(const nsIID& aIID,
|
||||
void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kClassIID, kIImageURLIID);
|
||||
static NS_DEFINE_IID(kURLIID, NS_IURL_IID);
|
||||
|
||||
if (aIID.Equals(kURLIID)) {
|
||||
*aInstancePtr = (void*) mURL;
|
||||
mURL->AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kClassIID)) {
|
||||
*aInstancePtr = (void*) this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*) ((nsISupports*)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(ImageURLImpl)
|
||||
|
||||
nsrefcnt ImageURLImpl::Release(void)
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
void
|
||||
ImageURLImpl::SetReader(ilINetReader *aReader)
|
||||
{
|
||||
if (mReader != nsnull) {
|
||||
NS_RELEASE(mReader);
|
||||
}
|
||||
|
||||
mReader = aReader;
|
||||
|
||||
if (mReader != nsnull) {
|
||||
NS_ADDREF(mReader);
|
||||
}
|
||||
}
|
||||
|
||||
ilINetReader *
|
||||
ImageURLImpl::GetReader()
|
||||
{
|
||||
if (mReader != nsnull) {
|
||||
NS_ADDREF(mReader);
|
||||
}
|
||||
|
||||
return mReader;
|
||||
}
|
||||
|
||||
int
|
||||
ImageURLImpl::GetContentLength()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char*
|
||||
ImageURLImpl::GetAddress()
|
||||
{
|
||||
if (mURL != nsnull) {
|
||||
return mURL->GetSpec();
|
||||
}
|
||||
else {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
time_t
|
||||
ImageURLImpl::GetExpires()
|
||||
{
|
||||
return 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
void
|
||||
ImageURLImpl::SetBackgroundLoad(PRBool aBgload)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewImageURL(ilIURL **aInstancePtrResult, const char *aURL)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
ilIURL *url = new ImageURLImpl(aURL);
|
||||
if (url == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return url->QueryInterface(kIImageURLIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
71
mozilla/gfx/src/nsMargin.h
Normal file
71
mozilla/gfx/src/nsMargin.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NSMARGIN_H
|
||||
#define NSMARGIN_H
|
||||
|
||||
#include "nsCoord.h"
|
||||
|
||||
struct nsMargin {
|
||||
nscoord left, top, right, bottom;
|
||||
|
||||
// Constructors
|
||||
nsMargin() {}
|
||||
nsMargin(const nsMargin& aMargin) {*this = aMargin;}
|
||||
nsMargin(nscoord aLeft, nscoord aTop,
|
||||
nscoord aRight, nscoord aBottom) {left = aLeft; top = aTop;
|
||||
right = aRight; bottom = aBottom;}
|
||||
|
||||
void SizeTo(nscoord aLeft, nscoord aTop,
|
||||
nscoord aRight, nscoord aBottom) {left = aLeft; top = aTop;
|
||||
right = aRight; bottom = aBottom;}
|
||||
void SizeBy(nscoord aLeft, nscoord aTop,
|
||||
nscoord aRight, nscoord aBottom) {left += aLeft; top += aTop;
|
||||
right += aRight; bottom += aBottom;}
|
||||
|
||||
// Overloaded operators. Note that '=' isn't defined so we'll get the
|
||||
// compiler generated default assignment operator
|
||||
PRBool operator==(const nsMargin& aMargin) const {
|
||||
return (PRBool) ((left == aMargin.left) && (top == aMargin.top) &&
|
||||
(right == aMargin.right) && (bottom == aMargin.bottom));
|
||||
}
|
||||
PRBool operator!=(const nsMargin& aMargin) const {
|
||||
return (PRBool) ((left != aMargin.left) || (top != aMargin.top) ||
|
||||
(right != aMargin.right) || (bottom != aMargin.bottom));
|
||||
}
|
||||
nsMargin operator+(const nsMargin& aMargin) const {
|
||||
return nsMargin(left + aMargin.left, top + aMargin.top,
|
||||
right + aMargin.right, bottom + aMargin.bottom);
|
||||
}
|
||||
nsMargin operator-(const nsMargin& aMargin) const {
|
||||
return nsMargin(left - aMargin.left, top - aMargin.top,
|
||||
right - aMargin.right, bottom - aMargin.bottom);
|
||||
}
|
||||
nsMargin& operator+=(const nsMargin& aMargin) {left += aMargin.left;
|
||||
top += aMargin.top;
|
||||
right += aMargin.right;
|
||||
bottom += aMargin.bottom;
|
||||
return *this;}
|
||||
nsMargin& operator-=(const nsMargin& aMargin) {left -= aMargin.left;
|
||||
top -= aMargin.top;
|
||||
right -= aMargin.right;
|
||||
bottom -= aMargin.bottom;
|
||||
return *this;}
|
||||
};
|
||||
|
||||
#endif /* NSMARGIN_H */
|
||||
61
mozilla/gfx/src/nsPoint.h
Normal file
61
mozilla/gfx/src/nsPoint.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NSPOINT_H
|
||||
#define NSPOINT_H
|
||||
|
||||
#include "nsCoord.h"
|
||||
|
||||
struct nsPoint {
|
||||
nscoord x, y;
|
||||
|
||||
// Constructors
|
||||
nsPoint() {}
|
||||
nsPoint(const nsPoint& aPoint) {x = aPoint.x; y = aPoint.y;}
|
||||
nsPoint(nscoord aX, nscoord aY) {x = aX; y = aY;}
|
||||
|
||||
void MoveTo(nscoord aX, nscoord aY) {x = aX; y = aY;}
|
||||
void MoveBy(nscoord aDx, nscoord aDy) {x += aDx; y += aDy;}
|
||||
|
||||
// Overloaded operators. Note that '=' isn't defined so we'll get the
|
||||
// compiler generated default assignment operator
|
||||
PRBool operator==(const nsPoint& aPoint) const {
|
||||
return (PRBool) ((x == aPoint.x) && (y == aPoint.y));
|
||||
}
|
||||
PRBool operator!=(const nsPoint& aPoint) const {
|
||||
return (PRBool) ((x != aPoint.x) || (y != aPoint.y));
|
||||
}
|
||||
nsPoint operator+(const nsPoint& aPoint) const {
|
||||
return nsPoint(x + aPoint.x, y + aPoint.y);
|
||||
}
|
||||
nsPoint operator-(const nsPoint& aPoint) const {
|
||||
return nsPoint(x - aPoint.x, y - aPoint.y);
|
||||
}
|
||||
nsPoint& operator+=(const nsPoint& aPoint) {
|
||||
x += aPoint.x;
|
||||
y += aPoint.y;
|
||||
return *this;
|
||||
}
|
||||
nsPoint& operator-=(const nsPoint& aPoint) {
|
||||
x -= aPoint.x;
|
||||
y -= aPoint.y;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* NSPOINT_H */
|
||||
173
mozilla/gfx/src/nsRect.cpp
Normal file
173
mozilla/gfx/src/nsRect.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsRect.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
#define MIN(a,b)\
|
||||
((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b)\
|
||||
((a) > (b) ? (a) : (b))
|
||||
|
||||
// Containment
|
||||
PRBool nsRect::Contains(nscoord aX, nscoord aY) const
|
||||
{
|
||||
return (PRBool) ((aX >= x) && (aY >= y) &&
|
||||
(aX < XMost()) && (aY < YMost()));
|
||||
}
|
||||
|
||||
PRBool nsRect::Contains(const nsRect &aRect) const
|
||||
{
|
||||
return (PRBool) ((aRect.x >= x) && (aRect.y >= y) &&
|
||||
(aRect.XMost() <= XMost()) && (aRect.YMost() <= YMost()));
|
||||
}
|
||||
|
||||
// Intersection. Returns TRUE if the receiver overlaps aRect and
|
||||
// FALSE otherwise
|
||||
PRBool nsRect::Intersects(const nsRect &aRect) const
|
||||
{
|
||||
return (PRBool) ((x < aRect.XMost()) && (y < aRect.YMost()) &&
|
||||
(aRect.x < XMost()) && (aRect.y < YMost()));
|
||||
}
|
||||
|
||||
// Computes the area in which aRect1 and aRect2 overlap and fills 'this' with
|
||||
// the result. Returns FALSE if the rectangles don't intersect.
|
||||
PRBool nsRect::IntersectRect(const nsRect &aRect1, const nsRect &aRect2)
|
||||
{
|
||||
nscoord xmost1 = aRect1.XMost();
|
||||
nscoord ymost1 = aRect1.YMost();
|
||||
nscoord xmost2 = aRect2.XMost();
|
||||
nscoord ymost2 = aRect2.YMost();
|
||||
nscoord temp;
|
||||
|
||||
x = MAX(aRect1.x, aRect2.x);
|
||||
y = MAX(aRect1.y, aRect2.y);
|
||||
|
||||
// Compute the destination width
|
||||
temp = MIN(xmost1, xmost2);
|
||||
if (temp <= x) {
|
||||
Empty();
|
||||
return PR_FALSE;
|
||||
}
|
||||
width = temp - x;
|
||||
|
||||
// Compute the destination height
|
||||
temp = MIN(ymost1, ymost2);
|
||||
if (temp <= y) {
|
||||
Empty();
|
||||
return PR_FALSE;
|
||||
}
|
||||
height = temp - y;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Computes the smallest rectangle that contains both aRect1 and aRect2 and
|
||||
// fills 'this' with the result. Returns FALSE if both aRect1 and aRect2 are
|
||||
// empty and TRUE otherwise
|
||||
PRBool nsRect::UnionRect(const nsRect &aRect1, const nsRect &aRect2)
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// Is aRect1 empty?
|
||||
if (aRect1.IsEmpty()) {
|
||||
if (aRect2.IsEmpty()) {
|
||||
// Both rectangles are empty which is an error
|
||||
Empty();
|
||||
result = PR_FALSE;
|
||||
} else {
|
||||
// aRect1 is empty so set the result to aRect2
|
||||
*this = aRect2;
|
||||
}
|
||||
} else if (aRect2.IsEmpty()) {
|
||||
// aRect2 is empty so set the result to aRect1
|
||||
*this = aRect1;
|
||||
} else {
|
||||
nscoord xmost1 = aRect1.XMost();
|
||||
nscoord xmost2 = aRect2.XMost();
|
||||
nscoord ymost1 = aRect1.YMost();
|
||||
nscoord ymost2 = aRect2.YMost();
|
||||
|
||||
// Compute the origin
|
||||
x = MIN(aRect1.x, aRect2.x);
|
||||
y = MIN(aRect1.y, aRect2.y);
|
||||
|
||||
// Compute the size
|
||||
width = MAX(xmost1, xmost2) - x;
|
||||
height = MAX(ymost1, ymost2) - y;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Inflate the rect by the specified width and height
|
||||
void nsRect::Inflate(nscoord aDx, nscoord aDy)
|
||||
{
|
||||
x -= aDx;
|
||||
y -= aDy;
|
||||
width += 2 * aDx;
|
||||
height += 2 * aDy;
|
||||
}
|
||||
|
||||
// Inflate the rect by the specified margin
|
||||
void nsRect::Inflate(const nsMargin &aMargin)
|
||||
{
|
||||
x -= aMargin.left;
|
||||
y -= aMargin.top;
|
||||
width += aMargin.left + aMargin.right;
|
||||
height += aMargin.top + aMargin.bottom;
|
||||
}
|
||||
|
||||
// Deflate the rect by the specified width and height
|
||||
void nsRect::Deflate(nscoord aDx, nscoord aDy)
|
||||
{
|
||||
x += aDx;
|
||||
y += aDy;
|
||||
width -= 2 * aDx;
|
||||
height -= 2 * aDy;
|
||||
}
|
||||
|
||||
// Deflate the rect by the specified margin
|
||||
void nsRect::Deflate(const nsMargin &aMargin)
|
||||
{
|
||||
x += aMargin.left;
|
||||
y += aMargin.top;
|
||||
width -= aMargin.left + aMargin.right;
|
||||
height -= aMargin.top + aMargin.bottom;
|
||||
}
|
||||
|
||||
// Diagnostics
|
||||
|
||||
FILE* operator<<(FILE* out, const nsRect& rect)
|
||||
{
|
||||
nsAutoString tmp;
|
||||
|
||||
// Output the coordinates in fractional points so they're easier to read
|
||||
tmp.Append("{");
|
||||
tmp.Append(NS_TWIPS_TO_POINTS_FLOAT(rect.x));
|
||||
tmp.Append(", ");
|
||||
tmp.Append(NS_TWIPS_TO_POINTS_FLOAT(rect.y));
|
||||
tmp.Append(", ");
|
||||
tmp.Append(NS_TWIPS_TO_POINTS_FLOAT(rect.width));
|
||||
tmp.Append(", ");
|
||||
tmp.Append(NS_TWIPS_TO_POINTS_FLOAT(rect.height));
|
||||
tmp.Append("}");
|
||||
fputs(tmp, out);
|
||||
return out;
|
||||
}
|
||||
129
mozilla/gfx/src/nsRect.h
Normal file
129
mozilla/gfx/src/nsRect.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NSRECT_H
|
||||
#define NSRECT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsCoord.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsMargin.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
struct NS_GFX nsRect {
|
||||
nscoord x, y;
|
||||
nscoord width, height;
|
||||
|
||||
// Constructors
|
||||
nsRect() {}
|
||||
nsRect(const nsRect& aRect) {*this = aRect;}
|
||||
nsRect(const nsPoint& aOrigin, const nsSize &aSize) {x = aOrigin.x; y = aOrigin.y;
|
||||
width = aSize.width; height = aSize.height;}
|
||||
nsRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) {x = aX; y = aY;
|
||||
width = aWidth; height = aHeight;}
|
||||
|
||||
// Emptiness. An empty rect is one that has no area, i.e. its width or height
|
||||
// is <= 0
|
||||
PRBool IsEmpty() const {
|
||||
return (PRBool) ((width <= 0) || (height <= 0));
|
||||
}
|
||||
void Empty() {width = height = 0;}
|
||||
|
||||
// Containment
|
||||
PRBool Contains(const nsRect& aRect) const;
|
||||
PRBool Contains(nscoord aX, nscoord aY) const;
|
||||
PRBool Contains(const nsPoint& aPoint) const {return Contains(aPoint.x, aPoint.y);}
|
||||
|
||||
// Intersection. Returns TRUE if the receiver overlaps aRect and
|
||||
// FALSE otherwise
|
||||
PRBool Intersects(const nsRect& aRect) const;
|
||||
|
||||
// Computes the area in which aRect1 and aRect2 overlap, and fills 'this' with
|
||||
// the result. Returns FALSE if the rectangles don't intersect, and sets 'this'
|
||||
// rect to be an empty rect.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
PRBool IntersectRect(const nsRect& aRect1, const nsRect& aRect2);
|
||||
|
||||
// Computes the smallest rectangle that contains both aRect1 and aRect2 and
|
||||
// fills 'this' with the result. Returns FALSE and sets 'this' rect to be an
|
||||
// empty rect if both aRect1 and aRect2 are empty
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
PRBool UnionRect(const nsRect& aRect1, const nsRect& aRect2);
|
||||
|
||||
// Accessors
|
||||
void SetRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) {
|
||||
x = aX; y = aY; width = aWidth; height = aHeight;
|
||||
}
|
||||
void MoveTo(nscoord aX, nscoord aY) {x = aX; y = aY;}
|
||||
void MoveTo(const nsPoint& aPoint) {x = aPoint.y; y = aPoint.y;}
|
||||
void MoveBy(nscoord aDx, nscoord aDy) {x += aDx; y += aDy;}
|
||||
void SizeTo(nscoord aWidth, nscoord aHeight) {width = aWidth; height = aHeight;}
|
||||
void SizeTo(const nsSize& aSize) {SizeTo(aSize.width, aSize.height);}
|
||||
void SizeBy(nscoord aDeltaWidth, nscoord aDeltaHeight) {width += aDeltaWidth;
|
||||
height += aDeltaHeight;}
|
||||
|
||||
// Inflate the rect by the specified width/height or margin
|
||||
void Inflate(nscoord aDx, nscoord aDy);
|
||||
void Inflate(const nsSize& aSize) {Inflate(aSize.width, aSize.height);}
|
||||
void Inflate(const nsMargin& aMargin);
|
||||
|
||||
// Deflate the rect by the specified width/height or margin
|
||||
void Deflate(nscoord aDx, nscoord aDy);
|
||||
void Deflate(const nsSize& aSize) {Deflate(aSize.width, aSize.height);}
|
||||
void Deflate(const nsMargin& aMargin);
|
||||
|
||||
// Overloaded operators. Note that '=' isn't defined so we'll get the
|
||||
// compiler generated default assignment operator.
|
||||
PRBool operator==(const nsRect& aRect) const {
|
||||
return (PRBool) ((IsEmpty() && aRect.IsEmpty()) ||
|
||||
((x == aRect.x) && (y == aRect.y) &&
|
||||
(width == aRect.width) && (height == aRect.height)));
|
||||
}
|
||||
PRBool operator!=(const nsRect& aRect) const {
|
||||
return (PRBool) !operator==(aRect);
|
||||
}
|
||||
nsRect operator+(const nsRect& aRect) const {
|
||||
return nsRect(x + aRect.x, y + aRect.y,
|
||||
width + aRect.width, height + aRect.height);
|
||||
}
|
||||
nsRect operator-(const nsRect& aRect) const {
|
||||
return nsRect(x - aRect.x, y - aRect.y,
|
||||
width - aRect.width, height - aRect.height);
|
||||
}
|
||||
nsRect& operator+=(const nsPoint& aPoint) {x += aPoint.x; y += aPoint.y; return *this;}
|
||||
nsRect& operator-=(const nsPoint& aPoint) {x -= aPoint.x; y -= aPoint.y; return *this;}
|
||||
|
||||
nsRect& operator*=(const float aScale) {x = NS_TO_INT_ROUND(x * aScale);
|
||||
y = NS_TO_INT_ROUND(y * aScale);
|
||||
width = NS_TO_INT_ROUND(width * aScale);
|
||||
height = NS_TO_INT_ROUND(height * aScale);
|
||||
return *this;}
|
||||
|
||||
// Helper methods for computing the extents
|
||||
nscoord XMost() const {return x + width;}
|
||||
nscoord YMost() const {return y + height;}
|
||||
};
|
||||
|
||||
// Diagnostics
|
||||
extern NS_GFX FILE* operator<<(FILE* out, const nsRect& rect);
|
||||
|
||||
#endif /* NSRECT_H */
|
||||
160
mozilla/gfx/src/nsRegion.h
Normal file
160
mozilla/gfx/src/nsRegion.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsRegion_h___
|
||||
#define nsRegion_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
// Function type passed into nsRegion::forEachRect, invoked
|
||||
// for each rectangle in a region
|
||||
typedef void (*nsRectInRegionFunc)(void *closure, nsRect& rect);
|
||||
|
||||
// An implementation of a region primitive that can be used to
|
||||
// represent arbitrary pixel areas. Probably implemented on top
|
||||
// of the native region primitive. The assumption is that, at worst,
|
||||
// it is a rectangle list.
|
||||
class nsRegion : public nsObjBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* copy operator equivalent that takes another region
|
||||
*
|
||||
* @param region to copy
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void setRegion(const nsRegion* region) = 0;
|
||||
|
||||
/**
|
||||
* copy operator equivalent that takes a rect
|
||||
*
|
||||
* @param rect to copy
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void setRect(const nsRect* rect) = 0;
|
||||
|
||||
/**
|
||||
* destructively intersect another region with this one
|
||||
*
|
||||
* @param region to intersect
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void intersect(const nsRegion* region) = 0;
|
||||
|
||||
/**
|
||||
* destructively intersect a rect with this region
|
||||
*
|
||||
* @param rect to intersect
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void intersect(const nsRect* rect) = 0;
|
||||
|
||||
/**
|
||||
* destructively union another region with this one
|
||||
*
|
||||
* @param region to union
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void union(const nsRegion* region) = 0;
|
||||
|
||||
/**
|
||||
* destructively union a rect with this region
|
||||
*
|
||||
* @param rect to union
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void union(const nsRect* rect) = 0;
|
||||
|
||||
/**
|
||||
* destructively subtract another region with this one
|
||||
*
|
||||
* @param region to subtract
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void subtract(const nsRegion* region) = 0;
|
||||
|
||||
/**
|
||||
* is this region empty? i.e. does it contain any pixels
|
||||
*
|
||||
* @param none
|
||||
* @return returns whether the region is empty
|
||||
*
|
||||
**/
|
||||
virtual nsbool isEmpty() = 0;
|
||||
|
||||
/**
|
||||
* == operator equivalent i.e. do the regions contain exactly
|
||||
* the same pixels
|
||||
*
|
||||
* @param region to compare
|
||||
* @return whether the regions are identical
|
||||
*
|
||||
**/
|
||||
virtual nsbool isEqual(const nsRegion* region) = 0;
|
||||
|
||||
/**
|
||||
* returns the bounding box of the region i.e. the smallest
|
||||
* rectangle that completely contains the region.
|
||||
*
|
||||
* @param rect to set to the bounding box
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void getBoundingBox(nsRect* rect) = 0;
|
||||
|
||||
/**
|
||||
* offsets the region in x and y
|
||||
*
|
||||
* @param xoffset pixel offset in x
|
||||
* @param yoffset pixel offset in y
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void offset(nsfloat xoffset, nsfloat yoffset) = 0;
|
||||
|
||||
/**
|
||||
* does the region completely contain the rectangle?
|
||||
*
|
||||
* @param rect to check for containment
|
||||
* @return true iff the rect is completely contained
|
||||
*
|
||||
**/
|
||||
virtual nsbool containsRect(const nsRect* rect) = 0;
|
||||
|
||||
/**
|
||||
* invoke a function for each rectangle in the region
|
||||
*
|
||||
* @param func Function to invoke for each rectangle
|
||||
* @param closure Arbitrary data to pass to the function
|
||||
* @return void
|
||||
*
|
||||
**/
|
||||
virtual void forEachRect(nsRectInRegionFunc* func, void* closure) = 0;
|
||||
};
|
||||
|
||||
extern NS_GFX nsRegion* NS_NewRegion(nsPresentationContext* context);
|
||||
|
||||
#endif // nsRegion_h___
|
||||
61
mozilla/gfx/src/nsSize.h
Normal file
61
mozilla/gfx/src/nsSize.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NSSIZE_H
|
||||
#define NSSIZE_H
|
||||
|
||||
#include "nsCoord.h"
|
||||
|
||||
// Maximum allowable size
|
||||
#define NS_MAXSIZE nscoord(1 << 30)
|
||||
|
||||
struct nsSize {
|
||||
nscoord width, height;
|
||||
|
||||
// Constructors
|
||||
nsSize() {}
|
||||
nsSize(const nsSize& aSize) {width = aSize.width; height = aSize.height;}
|
||||
nsSize(nscoord aWidth, nscoord aHeight) {width = aWidth; height = aHeight;}
|
||||
|
||||
void SizeTo(nscoord aWidth, nscoord aHeight) {width = aWidth; height = aHeight;}
|
||||
void SizeBy(nscoord aDeltaWidth, nscoord aDeltaHeight) {width += aDeltaWidth;
|
||||
height += aDeltaHeight;}
|
||||
|
||||
// Overloaded operators. Note that '=' isn't defined so we'll get the
|
||||
// compiler generated default assignment operator
|
||||
PRBool operator==(const nsSize& aSize) const {
|
||||
return (PRBool) ((width == aSize.width) && (height == aSize.height));
|
||||
}
|
||||
PRBool operator!=(const nsSize& aSize) const {
|
||||
return (PRBool) ((width != aSize.width) || (height != aSize.height));
|
||||
}
|
||||
nsSize operator+(const nsSize& aSize) const {
|
||||
return nsSize(width + aSize.width, height + aSize.height);
|
||||
}
|
||||
nsSize operator-(const nsSize& aSize) const {
|
||||
return nsSize(width - aSize.width, height - aSize.height);
|
||||
}
|
||||
nsSize& operator+=(const nsSize& aSize) {width += aSize.width;
|
||||
height += aSize.height;
|
||||
return *this;}
|
||||
nsSize& operator-=(const nsSize& aSize) {width -= aSize.width;
|
||||
height -= aSize.height;
|
||||
return *this;}
|
||||
};
|
||||
|
||||
#endif /* NSSIZE_H */
|
||||
565
mozilla/gfx/src/nsTransform2D.cpp
Normal file
565
mozilla/gfx/src/nsTransform2D.cpp
Normal file
@@ -0,0 +1,565 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsTransform2D.h"
|
||||
|
||||
void nsTransform2D :: SetToScale(float sx, float sy)
|
||||
{
|
||||
m01 = m10 = m20 = m21 = 0.0f;
|
||||
m00 = sx;
|
||||
m11 = sy;
|
||||
type = MG_2DSCALE;
|
||||
}
|
||||
|
||||
void nsTransform2D :: SetToTranslate(float tx, float ty)
|
||||
{
|
||||
m01 = m10 = 0.0f;
|
||||
m00 = m11 = 1.0f;
|
||||
m20 = tx;
|
||||
m21 = ty;
|
||||
type = MG_2DTRANSLATION;
|
||||
}
|
||||
|
||||
void nsTransform2D :: SetMatrix(nsTransform2D *aTransform2D)
|
||||
{
|
||||
m00 = aTransform2D->m00;
|
||||
m01 = aTransform2D->m01;
|
||||
m10 = aTransform2D->m10;
|
||||
m11 = aTransform2D->m11;
|
||||
m20 = aTransform2D->m20;
|
||||
m21 = aTransform2D->m21;
|
||||
type = aTransform2D->type;
|
||||
}
|
||||
|
||||
void nsTransform2D :: Concatenate(nsTransform2D *newxform)
|
||||
{
|
||||
float temp00, temp01, temp10, temp11;
|
||||
float new00, new01, new10, new11, new20, new21;
|
||||
PRUint16 newtype = newxform->type;
|
||||
|
||||
if (type == MG_2DIDENTITY)
|
||||
{
|
||||
//current matrix is identity
|
||||
|
||||
if (newtype != MG_2DIDENTITY)
|
||||
SetMatrix(newxform);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (newtype == MG_2DIDENTITY)
|
||||
return;
|
||||
else if ((type & MG_2DSCALE) != 0)
|
||||
{
|
||||
//current matrix is at least scale
|
||||
|
||||
if ((newtype & (MG_2DGENERAL | MG_2DSCALE)) != 0)
|
||||
{
|
||||
//new matrix is general or scale
|
||||
|
||||
if ((newtype & MG_2DTRANSLATION) != 0)
|
||||
{
|
||||
m20 += newxform->m20 * m00;
|
||||
m21 += newxform->m21 * m11;
|
||||
}
|
||||
|
||||
m00 *= newxform->m00;
|
||||
m11 *= newxform->m11;
|
||||
}
|
||||
else
|
||||
{
|
||||
//new matrix must be translation only
|
||||
|
||||
m20 += newxform->m20 * m00;
|
||||
m21 += newxform->m21 * m11;
|
||||
}
|
||||
}
|
||||
else if ((type & MG_2DGENERAL) != 0)
|
||||
{
|
||||
//current matrix is at least general
|
||||
|
||||
if ((newtype & MG_2DGENERAL) != 0)
|
||||
{
|
||||
//new matrix is general - worst case
|
||||
|
||||
temp00 = m00;
|
||||
temp01 = m01;
|
||||
temp10 = m10;
|
||||
temp11 = m11;
|
||||
|
||||
new00 = newxform->m00;
|
||||
new01 = newxform->m01;
|
||||
new10 = newxform->m10;
|
||||
new11 = newxform->m11;
|
||||
|
||||
if ((newtype & MG_2DTRANSLATION) != 0)
|
||||
{
|
||||
new20 = newxform->m20;
|
||||
new21 = newxform->m21;
|
||||
|
||||
m20 += new20 * temp00 + new21 * temp10;
|
||||
m21 += new20 * temp01 + new21 * temp11;
|
||||
}
|
||||
|
||||
m00 = new00 * temp00 + new01 * temp10;
|
||||
m01 = new00 * temp01 + new01 * temp11;
|
||||
m10 = new10 * temp00 + new11 * temp10;
|
||||
m11 = new10 * temp01 + new11 * temp11;
|
||||
}
|
||||
else if ((newtype & MG_2DSCALE) != 0)
|
||||
{
|
||||
//new matrix is at least scale
|
||||
|
||||
temp00 = m00;
|
||||
temp01 = m01;
|
||||
temp10 = m10;
|
||||
temp11 = m11;
|
||||
|
||||
new00 = newxform->m00;
|
||||
new11 = newxform->m11;
|
||||
|
||||
if ((newtype & MG_2DTRANSLATION) != 0)
|
||||
{
|
||||
new20 = newxform->m20;
|
||||
new21 = newxform->m21;
|
||||
|
||||
m20 += new20 * temp00 + new21 * temp10;
|
||||
m21 += new20 * temp01 + new21 * temp11;
|
||||
}
|
||||
|
||||
m00 = new00 * temp00;
|
||||
m01 = new00 * temp01;
|
||||
m10 = new11 * temp10;
|
||||
m11 = new11 * temp11;
|
||||
}
|
||||
else
|
||||
{
|
||||
//new matrix must be translation only
|
||||
|
||||
new20 = newxform->m20;
|
||||
new21 = newxform->m21;
|
||||
|
||||
m20 += new20 * m00 + new21 * m10;
|
||||
m21 += new20 * m01 + new21 * m11;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//current matrix is translation only
|
||||
|
||||
if ((newtype & (MG_2DGENERAL | MG_2DSCALE)) != 0)
|
||||
{
|
||||
//new matrix is general or scale
|
||||
|
||||
if ((newtype & MG_2DTRANSLATION) != 0)
|
||||
{
|
||||
m20 += newxform->m20;
|
||||
m21 += newxform->m21;
|
||||
}
|
||||
|
||||
m00 = newxform->m00;
|
||||
m11 = newxform->m11;
|
||||
}
|
||||
else
|
||||
{
|
||||
//new matrix must be translation only
|
||||
|
||||
m20 += newxform->m20;
|
||||
m21 += newxform->m21;
|
||||
}
|
||||
}
|
||||
|
||||
/* temp00 = m00;
|
||||
temp01 = m01;
|
||||
temp10 = m10;
|
||||
temp11 = m11;
|
||||
temp20 = m20;
|
||||
temp21 = m21;
|
||||
|
||||
new00 = newxform.m00;
|
||||
new01 = newxform.m01;
|
||||
new10 = newxform.m10;
|
||||
new11 = newxform.m11;
|
||||
new20 = newxform.m20;
|
||||
new21 = newxform.m21;
|
||||
|
||||
m00 = new00 * temp00 + new01 * temp10; // + new02 * temp20 == 0
|
||||
m01 = new00 * temp01 + new01 * temp11; // + new02 * temp21 == 0
|
||||
// m02 += new00 * temp02 + new01 * temp12; // + new02 * temp22 == 0
|
||||
m10 = new10 * temp00 + new11 * temp10; // + new12 * temp20 == 0
|
||||
m11 = new10 * temp01 + new11 * temp11; // + new12 * temp21 == 0
|
||||
// m12 += new10 * temp02 + new11 * temp12; // + new12 * temp22 == 0
|
||||
m20 = new20 * temp00 + new21 * temp10 + temp20; // + new22 * temp20 == temp20
|
||||
m21 = new20 * temp01 + new21 * temp11 + temp21; // + new22 * temp21 == temp21
|
||||
// m22 += new20 * temp02 + new21 * temp12; // + new22 * temp22 == 1
|
||||
*/
|
||||
type |= newtype;
|
||||
}
|
||||
|
||||
void nsTransform2D :: PreConcatenate(nsTransform2D *newxform)
|
||||
{
|
||||
float temp00, temp01, temp10, temp11, temp20, temp21;
|
||||
float new00, new01, new10, new11;
|
||||
|
||||
//this is totally unoptimized MMP
|
||||
|
||||
temp00 = m00;
|
||||
temp01 = m01;
|
||||
temp10 = m10;
|
||||
temp11 = m11;
|
||||
temp20 = m20;
|
||||
temp21 = m21;
|
||||
|
||||
new00 = newxform->m00;
|
||||
new01 = newxform->m01;
|
||||
new10 = newxform->m10;
|
||||
new11 = newxform->m11;
|
||||
|
||||
m00 = temp00 * new00 + temp01 * new10; // + temp02 * new20 == 0
|
||||
m01 = temp00 * new01 + temp01 * new11; // + temp02 * new21 == 0
|
||||
// m02 += temp00 * new02 + temp01 * new12; // + temp02 * new22 == 0
|
||||
m10 = temp10 * new00 + temp11 * new10; // + temp12 * new20 == 0
|
||||
m11 = temp10 * new01 + temp11 * new11; // + temp12 * new21 == 0
|
||||
// m12 += temp10 * new02 + temp11 * new12; // + temp12 * new22 == 0
|
||||
m20 = temp20 * new00 + temp21 * temp10 + temp20; // + temp22 * new20 == new20
|
||||
m21 = temp20 * new01 + temp21 * new11 + temp21; // + temp22 * new21 == new21
|
||||
// m22 += temp20 * new02 + temp21 * new12; // + temp22 * new22 == 1
|
||||
|
||||
type |= newxform->type;
|
||||
}
|
||||
|
||||
void nsTransform2D :: TransformNoXLate(float *ptX, float *ptY)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MG_2DIDENTITY:
|
||||
break;
|
||||
|
||||
case MG_2DSCALE:
|
||||
*ptX *= m00;
|
||||
*ptY *= m11;
|
||||
break;
|
||||
|
||||
default:
|
||||
case MG_2DGENERAL:
|
||||
x = *ptX;
|
||||
y = *ptY;
|
||||
|
||||
*ptX = x * m00 + y * m10;
|
||||
*ptY = x * m01 + y * m11;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTransform2D :: TransformNoXLateCoord(nscoord *ptX, nscoord *ptY)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MG_2DIDENTITY:
|
||||
break;
|
||||
|
||||
case MG_2DSCALE:
|
||||
*ptX = NS_TO_INT_ROUND(*ptX * m00);
|
||||
*ptY = NS_TO_INT_ROUND(*ptY * m11);
|
||||
break;
|
||||
|
||||
default:
|
||||
case MG_2DGENERAL:
|
||||
x = (float)*ptX;
|
||||
y = (float)*ptY;
|
||||
|
||||
*ptX = NS_TO_INT_ROUND(x * m00 + y * m10);
|
||||
*ptY = NS_TO_INT_ROUND(x * m01 + y * m11);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTransform2D :: Transform(float *ptX, float *ptY)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MG_2DIDENTITY:
|
||||
break;
|
||||
|
||||
case MG_2DTRANSLATION:
|
||||
*ptX += m20;
|
||||
*ptY += m21;
|
||||
break;
|
||||
|
||||
case MG_2DSCALE:
|
||||
*ptX *= m00;
|
||||
*ptY *= m11;
|
||||
break;
|
||||
|
||||
case MG_2DGENERAL:
|
||||
x = *ptX;
|
||||
y = *ptY;
|
||||
|
||||
*ptX = x * m00 + y * m10;
|
||||
*ptY = x * m01 + y * m11;
|
||||
|
||||
break;
|
||||
|
||||
case MG_2DSCALE | MG_2DTRANSLATION:
|
||||
*ptX = *ptX * m00 + m20;
|
||||
*ptY = *ptY * m11 + m21;
|
||||
break;
|
||||
|
||||
default:
|
||||
case MG_2DGENERAL | MG_2DTRANSLATION:
|
||||
x = *ptX;
|
||||
y = *ptY;
|
||||
|
||||
*ptX = x * m00 + y * m10 + m20;
|
||||
*ptY = x * m01 + y * m11 + m21;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTransform2D :: TransformCoord(nscoord *ptX, nscoord *ptY)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MG_2DIDENTITY:
|
||||
break;
|
||||
|
||||
case MG_2DTRANSLATION:
|
||||
*ptX += NS_TO_INT_ROUND(m20);
|
||||
*ptY += NS_TO_INT_ROUND(m21);
|
||||
break;
|
||||
|
||||
case MG_2DSCALE:
|
||||
*ptX = NS_TO_INT_ROUND(*ptX * m00);
|
||||
*ptY = NS_TO_INT_ROUND(*ptY * m11);
|
||||
break;
|
||||
|
||||
case MG_2DGENERAL:
|
||||
x = (float)*ptX;
|
||||
y = (float)*ptY;
|
||||
|
||||
*ptX = NS_TO_INT_ROUND(x * m00 + y * m10);
|
||||
*ptY = NS_TO_INT_ROUND(x * m01 + y * m11);
|
||||
|
||||
break;
|
||||
|
||||
case MG_2DSCALE | MG_2DTRANSLATION:
|
||||
*ptX = NS_TO_INT_ROUND(*ptX * m00 + m20);
|
||||
*ptY = NS_TO_INT_ROUND(*ptY * m11 + m21);
|
||||
break;
|
||||
|
||||
default:
|
||||
case MG_2DGENERAL | MG_2DTRANSLATION:
|
||||
x = (float)*ptX;
|
||||
y = (float)*ptY;
|
||||
|
||||
*ptX = NS_TO_INT_ROUND(x * m00 + y * m10 + m20);
|
||||
*ptY = NS_TO_INT_ROUND(x * m01 + y * m11 + m21);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTransform2D :: Transform(float *aX, float *aY, float *aWidth, float *aHeight)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MG_2DIDENTITY:
|
||||
break;
|
||||
|
||||
case MG_2DTRANSLATION:
|
||||
*aX += m20;
|
||||
*aY += m21;
|
||||
break;
|
||||
|
||||
case MG_2DSCALE:
|
||||
*aX *= m00;
|
||||
*aY *= m11;
|
||||
*aWidth *= m00;
|
||||
*aHeight *= m11;
|
||||
break;
|
||||
|
||||
case MG_2DGENERAL:
|
||||
x = *aX;
|
||||
y = *aY;
|
||||
|
||||
*aX = x * m00 + y * m10;
|
||||
*aY = x * m01 + y * m11;
|
||||
|
||||
x = *aWidth;
|
||||
y = *aHeight;
|
||||
|
||||
*aHeight = x * m00 + y * m10;
|
||||
*aHeight = x * m01 + y * m11;
|
||||
|
||||
break;
|
||||
|
||||
case MG_2DSCALE | MG_2DTRANSLATION:
|
||||
*aX = *aX * m00 + m20;
|
||||
*aY = *aY * m11 + m21;
|
||||
*aWidth *= m00;
|
||||
*aHeight *= m11;
|
||||
break;
|
||||
|
||||
default:
|
||||
case MG_2DGENERAL | MG_2DTRANSLATION:
|
||||
x = *aX;
|
||||
y = *aY;
|
||||
|
||||
*aX = x * m00 + y * m10 + m20;
|
||||
*aY = x * m01 + y * m11 + m21;
|
||||
|
||||
x = *aWidth;
|
||||
y = *aHeight;
|
||||
|
||||
*aWidth = x * m00 + y * m10;
|
||||
*aHeight = x * m01 + y * m11;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTransform2D :: TransformCoord(nscoord *aX, nscoord *aY, nscoord *aWidth, nscoord *aHeight)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MG_2DIDENTITY:
|
||||
break;
|
||||
|
||||
case MG_2DTRANSLATION:
|
||||
*aX += NS_TO_INT_ROUND(m20);
|
||||
*aY += NS_TO_INT_ROUND(m21);
|
||||
break;
|
||||
|
||||
case MG_2DSCALE:
|
||||
*aX = NS_TO_INT_ROUND(*aX * m00);
|
||||
*aY = NS_TO_INT_ROUND(*aY * m11);
|
||||
*aWidth = NS_TO_INT_ROUND(*aWidth * m00);
|
||||
*aHeight = NS_TO_INT_ROUND(*aHeight * m11);
|
||||
break;
|
||||
|
||||
case MG_2DGENERAL:
|
||||
x = (float)*aX;
|
||||
y = (float)*aY;
|
||||
|
||||
*aX = NS_TO_INT_ROUND(x * m00 + y * m10);
|
||||
*aY = NS_TO_INT_ROUND(x * m01 + y * m11);
|
||||
|
||||
x = (float)*aWidth;
|
||||
y = (float)*aHeight;
|
||||
|
||||
*aHeight = NS_TO_INT_ROUND(x * m00 + y * m10);
|
||||
*aHeight = NS_TO_INT_ROUND(x * m01 + y * m11);
|
||||
|
||||
break;
|
||||
|
||||
case MG_2DSCALE | MG_2DTRANSLATION:
|
||||
*aX = NS_TO_INT_ROUND(*aX * m00 + m20);
|
||||
*aY = NS_TO_INT_ROUND(*aY * m11 + m21);
|
||||
*aWidth = NS_TO_INT_ROUND(*aWidth * m00);
|
||||
*aHeight = NS_TO_INT_ROUND(*aHeight * m11);
|
||||
break;
|
||||
|
||||
default:
|
||||
case MG_2DGENERAL | MG_2DTRANSLATION:
|
||||
x = (float)*aX;
|
||||
y = (float)*aY;
|
||||
|
||||
*aX = NS_TO_INT_ROUND(x * m00 + y * m10 + m20);
|
||||
*aY = NS_TO_INT_ROUND(x * m01 + y * m11 + m21);
|
||||
|
||||
x = (float)*aWidth;
|
||||
y = (float)*aHeight;
|
||||
|
||||
*aWidth = NS_TO_INT_ROUND(x * m00 + y * m10);
|
||||
*aHeight = NS_TO_INT_ROUND(x * m01 + y * m11);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTransform2D :: AddTranslation(float ptX, float ptY)
|
||||
{
|
||||
if (type == MG_2DIDENTITY)
|
||||
{
|
||||
m20 = ptX;
|
||||
m21 = ptY;
|
||||
}
|
||||
else if ((type & MG_2DSCALE) != 0)
|
||||
{
|
||||
//current matrix is at least scale
|
||||
|
||||
m20 += ptX * m00;
|
||||
m21 += ptY * m11;
|
||||
}
|
||||
else if ((type & MG_2DGENERAL) != 0)
|
||||
{
|
||||
//current matrix is at least general
|
||||
|
||||
m20 += ptX * m00 + ptY * m10;
|
||||
m21 += ptX * m01 + ptY * m11;
|
||||
}
|
||||
else
|
||||
{
|
||||
m20 += ptX;
|
||||
m21 += ptY;
|
||||
}
|
||||
|
||||
type |= MG_2DTRANSLATION;
|
||||
}
|
||||
|
||||
void nsTransform2D :: AddScale(float ptX, float ptY)
|
||||
{
|
||||
if ((type == MG_2DIDENTITY) || (type == MG_2DTRANSLATION))
|
||||
{
|
||||
m00 = ptX;
|
||||
m11 = ptY;
|
||||
}
|
||||
else if ((type & MG_2DSCALE) != 0)
|
||||
{
|
||||
//current matrix is at least scale
|
||||
|
||||
m00 *= ptX;
|
||||
m11 *= ptY;
|
||||
}
|
||||
else if ((type & MG_2DGENERAL) != 0)
|
||||
{
|
||||
//current matrix is at least general
|
||||
|
||||
m00 *= ptX;
|
||||
m01 *= ptX;
|
||||
m10 *= ptY;
|
||||
m11 *= ptY;
|
||||
}
|
||||
|
||||
type |= MG_2DSCALE;
|
||||
}
|
||||
211
mozilla/gfx/src/nsTransform2D.h
Normal file
211
mozilla/gfx/src/nsTransform2D.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsTransform2D_h___
|
||||
#define nsTransform2D_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
#define MG_2DIDENTITY 0
|
||||
#define MG_2DTRANSLATION 1
|
||||
#define MG_2DSCALE 2
|
||||
#define MG_2DGENERAL 4
|
||||
|
||||
class NS_GFX nsTransform2D
|
||||
{
|
||||
private:
|
||||
//accelerators
|
||||
|
||||
float m00, m01, m10, m11, m20, m21;
|
||||
PRUint16 type;
|
||||
|
||||
public:
|
||||
//constructors
|
||||
|
||||
nsTransform2D(void) { SetToIdentity(); }
|
||||
nsTransform2D(nsTransform2D *aTransform2D) { SetMatrix(aTransform2D); }
|
||||
|
||||
//destructor
|
||||
|
||||
~nsTransform2D(void) { }
|
||||
|
||||
/**
|
||||
* get the type of this transform
|
||||
*
|
||||
* @param
|
||||
* @return type from above set
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
PRUint16 GetType(void) { return type; }
|
||||
|
||||
/**
|
||||
* set this transform to identity
|
||||
*
|
||||
* @param
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void SetToIdentity(void) { m01 = m10 = m20 = m21 = 0.0f; m00 = m11 = 1.0f; type = MG_2DIDENTITY; }
|
||||
|
||||
/**
|
||||
* set this transform to a scale
|
||||
*
|
||||
* @param sx, x scale
|
||||
* @param sy, y scale
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void SetToScale(float sx, float sy);
|
||||
|
||||
/**
|
||||
* set this transform to a translation
|
||||
*
|
||||
* @param tx, x translation
|
||||
* @param ty, y translation
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void SetToTranslate(float tx, float ty);
|
||||
|
||||
/**
|
||||
* get the translation portion of this transform
|
||||
*
|
||||
* @param pt, Point to return translation values in
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void GetTranslation(float *ptX, float *ptY) { *ptX = m20; *ptY = m21; }
|
||||
void GetTranslationCoord(nscoord *ptX, nscoord *ptY) { *ptX = NS_TO_INT_ROUND(m20); *ptY = NS_TO_INT_ROUND(m21); }
|
||||
|
||||
/**
|
||||
* get the X translation portion of this transform
|
||||
*
|
||||
* @param
|
||||
* @returns x component of translation
|
||||
* @exception
|
||||
**/
|
||||
|
||||
float GetXTranslation(void) { return m20; }
|
||||
nscoord GetXTranslationCoord(void) { return NS_TO_INT_ROUND(m20); }
|
||||
|
||||
/**
|
||||
* get the Y translation portion of this transform
|
||||
*
|
||||
* @param
|
||||
* @returns y component of translation
|
||||
* @exception
|
||||
**/
|
||||
|
||||
float GetYTranslation(void) { return m21; }
|
||||
nscoord GetYTranslationCoord(void) { return NS_TO_INT_ROUND(m21); }
|
||||
|
||||
/**
|
||||
* set this matrix and type from another Transform2D
|
||||
*
|
||||
* @param aTransform2D is the Transform2D to be copied from
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void SetMatrix(nsTransform2D *aTransform2D);
|
||||
|
||||
/**
|
||||
* post-multiply a new Transform
|
||||
*
|
||||
* @param newxform new Transform2D
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void Concatenate(nsTransform2D *newxform);
|
||||
|
||||
/**
|
||||
* pre-multiply a new Transform
|
||||
*
|
||||
* @param newxform new Transform2D
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void PreConcatenate(nsTransform2D *newxform);
|
||||
|
||||
/**
|
||||
* apply nontranslation portion of matrix to vector
|
||||
*
|
||||
* @param pt Point to transform
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void TransformNoXLate(float *ptX, float *ptY);
|
||||
void TransformNoXLateCoord(nscoord *ptX, nscoord *ptY);
|
||||
|
||||
/**
|
||||
* apply matrix to vector
|
||||
*
|
||||
* @param pt Point to transform
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void Transform(float *ptX, float *ptY);
|
||||
void TransformCoord(nscoord *ptX, nscoord *ptY);
|
||||
|
||||
/**
|
||||
* apply matrix to rect
|
||||
*
|
||||
* @param rect Rect to transform
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void Transform(float *aX, float *aY, float *aWidth, float *aHeight);
|
||||
void TransformCoord(nscoord *aX, nscoord *aY, nscoord *aWidth, nscoord *aHeight);
|
||||
|
||||
/**
|
||||
* add a translation to a Transform via x, y pair
|
||||
*
|
||||
* @param ptX x value to add as x translation
|
||||
* @param ptY y value to add as y translation
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void AddTranslation(float ptX, float ptY);
|
||||
|
||||
/**
|
||||
* add a scale to a Transform via x, y pair
|
||||
*
|
||||
* @param ptX x value to add as x scale
|
||||
* @param ptY y value to add as y scale
|
||||
* @exception
|
||||
* @author michaelp 09-25-97 1:56pm
|
||||
**/
|
||||
|
||||
void AddScale(float ptX, float ptY);
|
||||
};
|
||||
|
||||
#endif
|
||||
60
mozilla/gfx/src/windows/makefile.win
Normal file
60
mozilla/gfx/src/windows/makefile.win
Normal file
@@ -0,0 +1,60 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
DLLNAME = raptorgfxwin
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
#RESFILE = $(DLLNAME).res
|
||||
|
||||
MODULE=raptor
|
||||
|
||||
DEFINES =-D_IMPL_NS_GFXNONXP -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsDeviceContextWin.obj \
|
||||
.\$(OBJDIR)\nsRenderingContextWin.obj \
|
||||
.\$(OBJDIR)\nsFontMetricsWin.obj \
|
||||
.\$(OBJDIR)\nsImageWin.obj \
|
||||
.\$(OBJDIR)\nsGfxFactoryWin.obj \
|
||||
$(NULL)
|
||||
|
||||
LINCS= \
|
||||
-I$(PUBLIC)\raptor \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
-D_IMPL_NS_GFXNONXP \
|
||||
$(NULL)
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
$(DIST)\lib\raptorbase.lib \
|
||||
$(DIST)\lib\raptorgfx.lib \
|
||||
$(LIBNSPR)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\$(DLLNAME).dll
|
||||
229
mozilla/gfx/src/windows/nsDeviceContextWin.cpp
Normal file
229
mozilla/gfx/src/windows/nsDeviceContextWin.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsDeviceContextWin.h"
|
||||
#include "nsRenderingContextWin.h"
|
||||
#include "../nsGfxCIID.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID);
|
||||
|
||||
nsDeviceContextWin :: nsDeviceContextWin()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
HDC hdc = ::GetDC(NULL);
|
||||
|
||||
mTwipsToPixels = ::GetDeviceCaps(hdc, LOGPIXELSX) / NS_POINTS_TO_TWIPS_FLOAT(72.0f);
|
||||
mPixelsToTwips = 1.0f / mTwipsToPixels;
|
||||
|
||||
::ReleaseDC(NULL, hdc);
|
||||
|
||||
mFontCache = nsnull;
|
||||
|
||||
mDevUnitsToAppUnits = 1.0f;
|
||||
mAppUnitsToDevUnits = 1.0f;
|
||||
|
||||
mGammaValue = 1.0f;
|
||||
mGammaTable = new PRUint8[256];
|
||||
|
||||
mZoom = 1.0f;
|
||||
|
||||
mSurface = NULL;
|
||||
}
|
||||
|
||||
nsDeviceContextWin :: ~nsDeviceContextWin()
|
||||
{
|
||||
NS_IF_RELEASE(mFontCache);
|
||||
|
||||
if (NULL != mSurface)
|
||||
{
|
||||
DeleteDC(mSurface);
|
||||
mSurface = NULL;
|
||||
}
|
||||
|
||||
if (nsnull != mGammaTable)
|
||||
{
|
||||
delete mGammaTable;
|
||||
mGammaTable = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(nsDeviceContextWin, kDeviceContextIID)
|
||||
NS_IMPL_ADDREF(nsDeviceContextWin)
|
||||
NS_IMPL_RELEASE(nsDeviceContextWin)
|
||||
|
||||
nsresult nsDeviceContextWin :: Init()
|
||||
{
|
||||
for (PRInt32 cnt = 0; cnt < 256; cnt++)
|
||||
mGammaTable[cnt] = cnt;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetTwipsToDevUnits() const
|
||||
{
|
||||
return mTwipsToPixels;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetDevUnitsToTwips() const
|
||||
{
|
||||
return mPixelsToTwips;
|
||||
}
|
||||
|
||||
void nsDeviceContextWin :: SetAppUnitsToDevUnits(float aAppUnits)
|
||||
{
|
||||
mAppUnitsToDevUnits = aAppUnits;
|
||||
}
|
||||
|
||||
void nsDeviceContextWin :: SetDevUnitsToAppUnits(float aDevUnits)
|
||||
{
|
||||
mDevUnitsToAppUnits = aDevUnits;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetAppUnitsToDevUnits() const
|
||||
{
|
||||
return mAppUnitsToDevUnits;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetDevUnitsToAppUnits() const
|
||||
{
|
||||
return mDevUnitsToAppUnits;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetScrollBarWidth() const
|
||||
{
|
||||
return ::GetSystemMetrics(SM_CXVSCROLL) * mDevUnitsToAppUnits;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetScrollBarHeight() const
|
||||
{
|
||||
return ::GetSystemMetrics(SM_CXHSCROLL) * mDevUnitsToAppUnits;
|
||||
}
|
||||
|
||||
nsIRenderingContext * nsDeviceContextWin :: CreateRenderingContext(nsIView *aView)
|
||||
{
|
||||
nsIRenderingContext *pContext = nsnull;
|
||||
nsIWidget *win = aView->GetWidget();
|
||||
nsresult rv;
|
||||
|
||||
static NS_DEFINE_IID(kRCCID, NS_RENDERING_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kRCIID, NS_IRENDERING_CONTEXT_IID);
|
||||
|
||||
rv = NSRepository::CreateInstance(kRCCID, nsnull, kRCIID, (void **)&pContext);
|
||||
|
||||
if (NS_OK == rv)
|
||||
InitRenderingContext(pContext, win);
|
||||
|
||||
NS_IF_RELEASE(win);
|
||||
return pContext;
|
||||
}
|
||||
|
||||
void nsDeviceContextWin :: InitRenderingContext(nsIRenderingContext *aContext, nsIWidget *aWin)
|
||||
{
|
||||
aContext->Init(this, aWin);
|
||||
}
|
||||
|
||||
nsIFontCache* nsDeviceContextWin::GetFontCache()
|
||||
{
|
||||
if (nsnull == mFontCache) {
|
||||
if (NS_OK != CreateFontCache()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
NS_ADDREF(mFontCache);
|
||||
return mFontCache;
|
||||
}
|
||||
|
||||
void nsDeviceContextWin::FlushFontCache()
|
||||
{
|
||||
NS_RELEASE(mFontCache);
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextWin::CreateFontCache()
|
||||
{
|
||||
nsresult rv = NS_NewFontCache(&mFontCache);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
mFontCache->Init(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFontMetrics* nsDeviceContextWin::GetMetricsFor(const nsFont& aFont)
|
||||
{
|
||||
if (nsnull == mFontCache) {
|
||||
if (NS_OK != CreateFontCache()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
return mFontCache->GetMetricsFor(aFont);
|
||||
}
|
||||
|
||||
void nsDeviceContextWin :: SetZoom(float aZoom)
|
||||
{
|
||||
mZoom = aZoom;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetZoom() const
|
||||
{
|
||||
return mZoom;
|
||||
}
|
||||
|
||||
nsDrawingSurface nsDeviceContextWin :: GetDrawingSurface(nsIRenderingContext &aContext)
|
||||
{
|
||||
if (NULL == mSurface)
|
||||
mSurface = aContext.CreateDrawingSurface(nsnull);
|
||||
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
float nsDeviceContextWin :: GetGamma(void)
|
||||
{
|
||||
return mGammaValue;
|
||||
}
|
||||
|
||||
void nsDeviceContextWin :: SetGamma(float aGamma)
|
||||
{
|
||||
if (aGamma != mGammaValue)
|
||||
{
|
||||
//we don't need to-recorrect existing images for this case
|
||||
//so pass in 1.0 for the current gamma regardless of what it
|
||||
//really happens to be. existing images will get a one time
|
||||
//re-correction when they're rendered the next time. MMP
|
||||
|
||||
SetGammaTable(mGammaTable, 1.0f, aGamma);
|
||||
|
||||
mGammaValue = aGamma;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint8 * nsDeviceContextWin :: GetGammaTable(void)
|
||||
{
|
||||
//XXX we really need to ref count this somehow. MMP
|
||||
|
||||
return mGammaTable;
|
||||
}
|
||||
|
||||
void nsDeviceContextWin :: SetGammaTable(PRUint8 * aTable, float aCurrentGamma, float aNewGamma)
|
||||
{
|
||||
double fgval = (1.0f / aCurrentGamma) * (1.0f / aNewGamma);
|
||||
|
||||
for (PRInt32 cnt = 0; cnt < 256; cnt++)
|
||||
aTable[cnt] = (PRUint8)(pow((double)cnt * (1. / 256.), fgval) * 255.99999999);
|
||||
}
|
||||
85
mozilla/gfx/src/windows/nsDeviceContextWin.h
Normal file
85
mozilla/gfx/src/windows/nsDeviceContextWin.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsDeviceContextWin_h___
|
||||
#define nsDeviceContextWin_h___
|
||||
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsUnitConversion.h"
|
||||
#include "nsIFontCache.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include <windows.h>
|
||||
|
||||
class nsDeviceContextWin : public nsIDeviceContext
|
||||
{
|
||||
public:
|
||||
nsDeviceContextWin();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init();
|
||||
|
||||
virtual nsIRenderingContext * CreateRenderingContext(nsIView *aView);
|
||||
virtual void InitRenderingContext(nsIRenderingContext *aContext, nsIWidget *aWidget);
|
||||
|
||||
virtual float GetTwipsToDevUnits() const;
|
||||
virtual float GetDevUnitsToTwips() const;
|
||||
|
||||
virtual void SetAppUnitsToDevUnits(float aAppUnits);
|
||||
virtual void SetDevUnitsToAppUnits(float aDevUnits);
|
||||
|
||||
virtual float GetAppUnitsToDevUnits() const;
|
||||
virtual float GetDevUnitsToAppUnits() const;
|
||||
|
||||
virtual float GetScrollBarWidth() const;
|
||||
virtual float GetScrollBarHeight() const;
|
||||
|
||||
virtual nsIFontCache * GetFontCache();
|
||||
virtual void FlushFontCache();
|
||||
|
||||
virtual nsIFontMetrics* GetMetricsFor(const nsFont& aFont);
|
||||
|
||||
virtual void SetZoom(float aZoom);
|
||||
virtual float GetZoom() const;
|
||||
|
||||
virtual nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext);
|
||||
|
||||
virtual float GetGamma(void);
|
||||
virtual void SetGamma(float aGamma);
|
||||
virtual PRUint8 * GetGammaTable(void);
|
||||
|
||||
protected:
|
||||
~nsDeviceContextWin();
|
||||
|
||||
nsresult CreateFontCache();
|
||||
void SetGammaTable(PRUint8 * aTable, float aCurrentGamma, float aNewGamma);
|
||||
|
||||
float mTwipsToPixels;
|
||||
float mPixelsToTwips;
|
||||
float mAppUnitsToDevUnits;
|
||||
float mDevUnitsToAppUnits;
|
||||
nsIFontCache *mFontCache;
|
||||
float mZoom;
|
||||
HDC mSurface;
|
||||
float mGammaValue;
|
||||
PRUint8 *mGammaTable;
|
||||
};
|
||||
|
||||
#endif /* nsDeviceContextWin_h___ */
|
||||
237
mozilla/gfx/src/windows/nsFontMetricsWin.cpp
Normal file
237
mozilla/gfx/src/windows/nsFontMetricsWin.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsFontMetricsWin.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFontMetricsIID, NS_IFONT_METRICS_IID);
|
||||
|
||||
nsFontMetricsWin :: nsFontMetricsWin()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsFontMetricsWin :: ~nsFontMetricsWin()
|
||||
{
|
||||
if (nsnull != mFont)
|
||||
{
|
||||
delete mFont;
|
||||
mFont = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFontMetricsWin, kIFontMetricsIID)
|
||||
|
||||
// Note: The presentation context has a reference to this font
|
||||
// metrics, therefore avoid circular references by not AddRef'ing the
|
||||
// presentation context.
|
||||
nsresult nsFontMetricsWin :: Init(const nsFont& aFont, nsIDeviceContext* aCX)
|
||||
{
|
||||
mFont = new nsFont(aFont);
|
||||
mContext = aCX;
|
||||
|
||||
RealizeFont();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX this function is a hack; the only logical font names we should
|
||||
// support are the one used by css.
|
||||
const char* nsFontMetricsWin::MapFamilyToFont(const nsString& aLogicalFontName)
|
||||
{
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Times Roman")) {
|
||||
return "Times New Roman";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Times")) {
|
||||
return "Times New Roman";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Unicode")) {
|
||||
return "Bitstream Cyberbit";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Courier")) {
|
||||
return "Courier New";
|
||||
}
|
||||
|
||||
// the CSS generic names
|
||||
if (aLogicalFontName.EqualsIgnoreCase("serif")) {
|
||||
return "Times New Roman";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("sans-serif")) {
|
||||
return "Arial";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("cursive")) {
|
||||
// return "XXX";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("fantasy")) {
|
||||
// return "XXX";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("monospace")) {
|
||||
return "Courier New";
|
||||
}
|
||||
return "Arial";/* XXX for now */
|
||||
}
|
||||
|
||||
void nsFontMetricsWin::RealizeFont()
|
||||
{
|
||||
// Fill in logFont structure; stolen from awt
|
||||
LOGFONT logFont;
|
||||
logFont.lfWidth = 0;
|
||||
logFont.lfEscapement = 0;
|
||||
logFont.lfOrientation = 0;
|
||||
logFont.lfUnderline =
|
||||
(mFont->decorations & NS_FONT_DECORATION_UNDERLINE)
|
||||
? TRUE : FALSE;
|
||||
logFont.lfStrikeOut =
|
||||
(mFont->decorations & NS_FONT_DECORATION_LINE_THROUGH)
|
||||
? TRUE : FALSE;
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
logFont.lfQuality = DEFAULT_QUALITY;
|
||||
logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
logFont.lfWeight = (mFont->weight > NS_FONT_WEIGHT_NORMAL) // XXX ??? this should be smarter
|
||||
? FW_BOLD : FW_NORMAL;
|
||||
logFont.lfItalic = (mFont->style & NS_FONT_STYLE_ITALIC)
|
||||
? TRUE : FALSE;
|
||||
float t2p = mContext->GetAppUnitsToDevUnits();
|
||||
logFont.lfHeight = (LONG)(-mFont->size * t2p);
|
||||
strncpy(logFont.lfFaceName,
|
||||
MapFamilyToFont(mFont->name),
|
||||
LF_FACESIZE);
|
||||
|
||||
// Create font handle from font spec
|
||||
mFontHandle = ::CreateFontIndirect(&logFont);
|
||||
//fprintf(stderr, "fFontHandle=%x\n", fFontHandle);
|
||||
|
||||
// Find font metrics and character widths
|
||||
HWND win = ::GetDesktopWindow();
|
||||
HDC dc = ::GetDC(win);
|
||||
::SelectObject(dc, (HGDIOBJ) mFontHandle);
|
||||
|
||||
// Get font metrics
|
||||
float p2t = mContext->GetDevUnitsToAppUnits();
|
||||
TEXTMETRIC metrics;
|
||||
::GetTextMetrics(dc, &metrics);
|
||||
mHeight = nscoord(metrics.tmHeight * p2t);
|
||||
mAscent = nscoord(metrics.tmAscent * p2t);
|
||||
mDescent = nscoord(metrics.tmDescent * p2t);
|
||||
mLeading = nscoord(metrics.tmInternalLeading * p2t);
|
||||
mMaxAscent = nscoord(metrics.tmAscent * p2t);
|
||||
mMaxDescent = nscoord(metrics.tmDescent * p2t);
|
||||
mMaxAdvance = nscoord(metrics.tmMaxCharWidth * p2t);
|
||||
#if 0
|
||||
fprintf(stderr, "fontmetrics: height=%d ascent=%d descent=%d leading=%d\n",
|
||||
fHeight, fAscent, fDescent, fLeading);
|
||||
#endif
|
||||
|
||||
// Get character widths in twips
|
||||
int widths[256];
|
||||
::GetCharWidth(dc, 0, 255, widths);
|
||||
nscoord* tp = mCharWidths;
|
||||
int* fp = widths;
|
||||
int* end = fp + 256;
|
||||
while (fp < end) {
|
||||
*tp++ = nscoord( *fp++ * p2t );
|
||||
}
|
||||
|
||||
::ReleaseDC(win, dc);
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetWidth(char ch)
|
||||
{
|
||||
return mCharWidths[PRUint8(ch)];
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetWidth(PRUnichar ch)
|
||||
{
|
||||
if (ch < 256) {
|
||||
return mCharWidths[ch];
|
||||
}
|
||||
return 0;/* XXX */
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetWidth(const nsString& aString)
|
||||
{
|
||||
return GetWidth(aString.GetUnicode(), aString.Length());
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetWidth(const char *aString)
|
||||
{
|
||||
// XXX use native text measurement routine
|
||||
nscoord sum = 0;
|
||||
PRUint8 ch;
|
||||
while ((ch = PRUint8(*aString++)) != 0) {
|
||||
sum += mCharWidths[ch];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetWidth(const PRUnichar *aString, PRUint32 aLength)
|
||||
{
|
||||
// XXX use native text measurement routine
|
||||
nscoord sum = 0;
|
||||
while (aLength != 0) {
|
||||
PRUnichar ch = *aString++;
|
||||
if (ch < 256) {
|
||||
sum += mCharWidths[ch];
|
||||
} else {
|
||||
// XXX not yet
|
||||
}
|
||||
--aLength;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetHeight()
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetLeading()
|
||||
{
|
||||
return mLeading;
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetMaxAscent()
|
||||
{
|
||||
return mMaxAscent;
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetMaxDescent()
|
||||
{
|
||||
return mMaxDescent;
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsWin :: GetMaxAdvance()
|
||||
{
|
||||
return mMaxAdvance;
|
||||
}
|
||||
|
||||
const nscoord * nsFontMetricsWin :: GetWidths()
|
||||
{
|
||||
return mCharWidths;
|
||||
}
|
||||
|
||||
const nsFont& nsFontMetricsWin :: GetFont()
|
||||
{
|
||||
return *mFont;
|
||||
}
|
||||
|
||||
nsFontHandle nsFontMetricsWin::GetFontHandle()
|
||||
{
|
||||
return mFontHandle;
|
||||
}
|
||||
77
mozilla/gfx/src/windows/nsFontMetricsWin.h
Normal file
77
mozilla/gfx/src/windows/nsFontMetricsWin.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsFontMetricsWin_h__
|
||||
#define nsFontMetricsWin_h__
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUnitConversion.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
class nsFontMetricsWin : public nsIFontMetrics
|
||||
{
|
||||
public:
|
||||
nsFontMetricsWin();
|
||||
~nsFontMetricsWin();
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
nsCRT::zero(rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(const nsFont& aFont, nsIDeviceContext* aContext);
|
||||
virtual nscoord GetWidth(char aC);
|
||||
virtual nscoord GetWidth(PRUnichar aC);
|
||||
virtual nscoord GetWidth(const nsString& aString);
|
||||
virtual nscoord GetWidth(const char *aString);
|
||||
virtual nscoord GetWidth(const PRUnichar *aString, PRUint32 aLength);
|
||||
virtual nscoord GetHeight();
|
||||
virtual nscoord GetLeading();
|
||||
virtual nscoord GetMaxAscent();
|
||||
virtual nscoord GetMaxDescent();
|
||||
virtual nscoord GetMaxAdvance();
|
||||
virtual const nscoord *GetWidths();
|
||||
virtual const nsFont& GetFont();
|
||||
virtual nsFontHandle GetFontHandle();
|
||||
|
||||
protected:
|
||||
void RealizeFont();
|
||||
static const char* MapFamilyToFont(const nsString& aLogicalFontName);
|
||||
|
||||
nsFont *mFont;
|
||||
nsIDeviceContext *mContext;
|
||||
nscoord mCharWidths[256];
|
||||
nscoord mHeight;
|
||||
nscoord mAscent;
|
||||
nscoord mDescent;
|
||||
nscoord mLeading;
|
||||
nscoord mMaxAscent;
|
||||
nscoord mMaxDescent;
|
||||
nscoord mMaxAdvance;
|
||||
HFONT mFontHandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
171
mozilla/gfx/src/windows/nsGfxFactoryWin.cpp
Normal file
171
mozilla/gfx/src/windows/nsGfxFactoryWin.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "../nsGfxCIID.h"
|
||||
#include "nsFontMetricsWin.h"
|
||||
#include "nsRenderingContextWin.h"
|
||||
#include "nsImageWin.h"
|
||||
#include "nsDeviceContextWin.h"
|
||||
|
||||
static NS_DEFINE_IID(kCFontMetrics, NS_FONT_METRICS_CID);
|
||||
static NS_DEFINE_IID(kCRenderingContext, NS_RENDERING_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kCImage, NS_IMAGE_CID);
|
||||
static NS_DEFINE_IID(kCDeviceContext, NS_DEVICE_CONTEXT_CID);
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
|
||||
class nsGfxFactoryWin : public nsIFactory
|
||||
{
|
||||
public:
|
||||
// nsISupports methods
|
||||
NS_IMETHOD QueryInterface(const nsIID &aIID,
|
||||
void **aResult);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
// nsIFactory methods
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
||||
const nsIID &aIID,
|
||||
void **aResult);
|
||||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
nsGfxFactoryWin(const nsCID &aClass);
|
||||
~nsGfxFactoryWin();
|
||||
|
||||
private:
|
||||
nsrefcnt mRefCnt;
|
||||
nsCID mClassID;
|
||||
};
|
||||
|
||||
nsGfxFactoryWin::nsGfxFactoryWin(const nsCID &aClass)
|
||||
{
|
||||
mRefCnt = 0;
|
||||
mClassID = aClass;
|
||||
}
|
||||
|
||||
nsGfxFactoryWin::~nsGfxFactoryWin()
|
||||
{
|
||||
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
|
||||
}
|
||||
|
||||
nsresult nsGfxFactoryWin::QueryInterface(const nsIID &aIID,
|
||||
void **aResult)
|
||||
{
|
||||
if (aResult == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Always NULL result, in case of failure
|
||||
*aResult = NULL;
|
||||
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aResult = (void *)(nsISupports*)this;
|
||||
} else if (aIID.Equals(kIFactoryIID)) {
|
||||
*aResult = (void *)(nsIFactory*)this;
|
||||
}
|
||||
|
||||
if (*aResult == NULL) {
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef(); // Increase reference count for caller
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsrefcnt nsGfxFactoryWin::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt nsGfxFactoryWin::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
delete this;
|
||||
return 0; // Don't access mRefCnt after deleting!
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
|
||||
const nsIID &aIID,
|
||||
void **aResult)
|
||||
{
|
||||
if (aResult == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aResult = NULL;
|
||||
|
||||
nsISupports *inst = nsnull;
|
||||
|
||||
if (mClassID.Equals(kCFontMetrics)) {
|
||||
inst = (nsISupports *)new nsFontMetricsWin();
|
||||
}
|
||||
else if (mClassID.Equals(kCDeviceContext)) {
|
||||
inst = (nsISupports *)new nsDeviceContextWin();
|
||||
}
|
||||
else if (mClassID.Equals(kCRenderingContext)) {
|
||||
inst = (nsISupports *)new nsRenderingContextWin();
|
||||
}
|
||||
else if (mClassID.Equals(kCImage)) {
|
||||
inst = (nsISupports *)new nsImageWin();
|
||||
}
|
||||
|
||||
if (inst == NULL) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult res = inst->QueryInterface(aIID, aResult);
|
||||
|
||||
if (res != NS_OK) {
|
||||
// We didn't get the right interface, so clean up
|
||||
delete inst;
|
||||
}
|
||||
// else {
|
||||
// inst->Release();
|
||||
// }
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
nsresult nsGfxFactoryWin::LockFactory(PRBool aLock)
|
||||
{
|
||||
// Not implemented in simplest case.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// return the proper factory to the caller
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aFactory = new nsGfxFactoryWin(aClass);
|
||||
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory);
|
||||
}
|
||||
777
mozilla/gfx/src/windows/nsImageWin.cpp
Normal file
777
mozilla/gfx/src/windows/nsImageWin.cpp
Normal file
@@ -0,0 +1,777 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsImageWin.h"
|
||||
#include "nsRenderingContextWin.h"
|
||||
|
||||
static NS_DEFINE_IID(kIImageIID, NS_IIMAGE_IID);
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
nsImageWin :: nsImageWin()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mImageBits = nsnull;
|
||||
mHBitmap = nsnull;
|
||||
mHPalette = nsnull;
|
||||
mAlphaBits = nsnull;
|
||||
mColorMap = nsnull;
|
||||
mBHead = nsnull;
|
||||
|
||||
CleanUp(PR_TRUE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
nsImageWin :: ~nsImageWin()
|
||||
{
|
||||
CleanUp(PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImageWin, kIImageIID);
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
nsresult nsImageWin :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
mHBitmap = nsnull;
|
||||
mHPalette = nsnull;
|
||||
CleanUp(PR_TRUE);
|
||||
ComputePaletteSize(aDepth);
|
||||
|
||||
if (mNumPalleteColors >= 0)
|
||||
{
|
||||
mBHead = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * mNumPalleteColors];
|
||||
mBHead->biSize = sizeof(BITMAPINFOHEADER);
|
||||
mBHead->biWidth = aWidth;
|
||||
mBHead->biHeight = aHeight;
|
||||
mBHead->biPlanes = 1;
|
||||
mBHead->biBitCount = (unsigned short) aDepth;
|
||||
mBHead->biCompression = BI_RGB;
|
||||
mBHead->biSizeImage = 0; // not compressed, so we dont need this to be set
|
||||
mBHead->biXPelsPerMeter = 0;
|
||||
mBHead->biYPelsPerMeter = 0;
|
||||
mBHead->biClrUsed = mNumPalleteColors;
|
||||
mBHead->biClrImportant = mNumPalleteColors;
|
||||
|
||||
ComputeMetrics();
|
||||
memset(mColorTable, 0, sizeof(RGBQUAD) * mNumPalleteColors);
|
||||
mImageBits = new unsigned char[mSizeImage];
|
||||
memset(mImageBits, 128, mSizeImage);
|
||||
this->MakePalette();
|
||||
|
||||
if (aMaskRequirements != nsMaskRequirements_kNoMask)
|
||||
{
|
||||
mAlphaWidth=aWidth;
|
||||
mAlphaWidth=aHeight;
|
||||
mAlphaBits = new unsigned char[aWidth * aHeight];
|
||||
}
|
||||
else
|
||||
{
|
||||
mAlphaBits = 0;
|
||||
mAlphaWidth=0;
|
||||
mAlphaHeight=0;
|
||||
}
|
||||
|
||||
mColorMap = new nsColorMap;
|
||||
|
||||
if (mColorMap != nsnull)
|
||||
{
|
||||
mColorMap->NumColors = mNumPalleteColors;
|
||||
mColorMap->Index = new PRUint8[3 * mNumPalleteColors];
|
||||
|
||||
// XXX Note: I added this because purify claims that we make a
|
||||
// copy of the memory (which we do!). I'm not sure if this
|
||||
// matters or not, but this shutup purify.
|
||||
memset(mColorMap->Index, 0, sizeof(PRUint8) * (3 * mNumPalleteColors));
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// set up the pallete to the passed in color array, RGB only in this array
|
||||
void nsImageWin :: ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
|
||||
{
|
||||
PRInt32 i;
|
||||
PRUint8 *cpointer;
|
||||
|
||||
if (aFlags & nsImageUpdateFlags_kColorMapChanged)
|
||||
{
|
||||
PRUint8 *gamma = aContext->GetGammaTable();
|
||||
|
||||
if (mColorMap->NumColors > 0)
|
||||
{
|
||||
cpointer = mColorTable;
|
||||
|
||||
for(i = 0; i < mColorMap->NumColors; i++)
|
||||
{
|
||||
*cpointer++ = gamma[mColorMap->Index[(3 * i) + 2]];
|
||||
*cpointer++ = gamma[mColorMap->Index[(3 * i) + 1]];
|
||||
*cpointer++ = gamma[mColorMap->Index[(3 * i)]];
|
||||
*cpointer++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
this->MakePalette();
|
||||
}
|
||||
else if ((aFlags & nsImageUpdateFlags_kBitsChanged) &&
|
||||
(nsnull != aUpdateRect))
|
||||
{
|
||||
if (mNumPalleteColors == 0)
|
||||
{
|
||||
PRInt32 x, y, span = CalcBytesSpan(mBHead->biWidth), idx;
|
||||
PRUint8 *pixels = mImageBits + aUpdateRect->y * span + aUpdateRect->x * 3;
|
||||
PRUint8 *gamma = aContext->GetGammaTable();
|
||||
|
||||
for (y = 0; y < aUpdateRect->height; y++)
|
||||
{
|
||||
for (x = 0, idx = 0; x < aUpdateRect->width; x++)
|
||||
{
|
||||
pixels[idx] = gamma[pixels[idx]];
|
||||
idx++;
|
||||
pixels[idx] = gamma[pixels[idx]];
|
||||
idx++;
|
||||
pixels[idx] = gamma[pixels[idx]];
|
||||
idx++;
|
||||
}
|
||||
|
||||
pixels += span;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRUintn nsImageWin :: UsePalette(HDC* aHdc, PRBool bBackground)
|
||||
{
|
||||
if (mHPalette == nsnull)
|
||||
return 0;
|
||||
|
||||
HPALETTE hOldPalette = ::SelectPalette(aHdc, mHPalette, (bBackground == PR_TRUE) ? TRUE : FALSE);
|
||||
|
||||
return ::RealizePalette(aHdc);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// Draw the bitmap, this method has a source and destination coordinates
|
||||
PRBool nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
PRUint32 value,error;
|
||||
HDC the_hdc = (HDC)aSurface;
|
||||
|
||||
if (mBHead == nsnull)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!IsOptimized())
|
||||
{
|
||||
value = ::StretchDIBits(the_hdc,aDX,aDY,aDWidth,aDHeight,
|
||||
0,0,aSWidth, aSHeight,
|
||||
mImageBits,(LPBITMAPINFO)mBHead,DIB_RGB_COLORS,SRCCOPY);
|
||||
if (value == GDI_ERROR)
|
||||
error = ::GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIDeviceContext *dx = aContext.GetDeviceContext();
|
||||
HDC srcdc = dx->GetDrawingSurface(aContext);
|
||||
|
||||
if (NULL != srcdc)
|
||||
{
|
||||
HBITMAP oldbits = ::SelectObject(srcdc, mHBitmap);
|
||||
|
||||
if (!::StretchBlt(the_hdc, aDX, aDY, aDWidth, aDHeight, srcdc, aSX, aSY,
|
||||
aSWidth, aSHeight, SRCCOPY))
|
||||
error = ::GetLastError();
|
||||
|
||||
if (nsnull != oldbits)
|
||||
::SelectObject(srcdc, oldbits);
|
||||
}
|
||||
|
||||
NS_RELEASE(dx);
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// Draw the bitmap, this draw just has destination coordinates
|
||||
PRBool nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
PRUint32 value,error;
|
||||
HDC the_hdc = (HDC)aSurface;
|
||||
|
||||
if (mBHead == nsnull)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!IsOptimized())
|
||||
{
|
||||
value = ::StretchDIBits(the_hdc,aX,aY,aWidth,aHeight,
|
||||
0,0,mBHead->biWidth, mBHead->biHeight,
|
||||
mImageBits,(LPBITMAPINFO)mBHead,DIB_RGB_COLORS,SRCCOPY);
|
||||
|
||||
if (value == GDI_ERROR)
|
||||
error = ::GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIDeviceContext *dx = aContext.GetDeviceContext();
|
||||
HDC srcdc = dx->GetDrawingSurface(aContext);
|
||||
|
||||
if (NULL != srcdc)
|
||||
{
|
||||
HBITMAP oldbits = ::SelectObject(srcdc, mHBitmap);
|
||||
//if((aWidth == mBHead->biWidth) && (aHeight == mBHead->biHeight))
|
||||
//BitBlt(the_hdc,aX,aY,aWidth,aHeight,mOptimizeDC,0,0,SRCCOPY);
|
||||
|
||||
if (!::StretchBlt(the_hdc, aX, aY, aWidth, aHeight, srcdc, 0, 0,
|
||||
mBHead->biWidth, mBHead->biHeight, SRCCOPY))
|
||||
error = ::GetLastError();
|
||||
|
||||
if (nsnull != oldbits)
|
||||
::SelectObject(srcdc, oldbits);
|
||||
}
|
||||
|
||||
NS_RELEASE(dx);
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void nsImageWin::CompositeImage(nsIImage *aTheImage, nsPoint *aULLocation,nsBlendQuality aBlendQuality)
|
||||
{
|
||||
// call the correct sub routine for each blend
|
||||
|
||||
if ((mNumBytesPixel == 3) && (((nsImageWin *)aTheImage)->mNumBytesPixel == 3))
|
||||
this->Comp24to24((nsImageWin*)aTheImage, aULLocation,aBlendQuality);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// lets build an alpha mask from this image
|
||||
PRBool nsImageWin::SetAlphaMask(nsIImage *aTheMask)
|
||||
{
|
||||
PRInt32 num;
|
||||
PRUint8 *srcbits;
|
||||
|
||||
if (aTheMask && (((nsImageWin*)aTheMask)->mNumBytesPixel == 1))
|
||||
{
|
||||
mLocation.x = 0;
|
||||
mLocation.y = 0;
|
||||
mAlphaDepth = 8;
|
||||
mAlphaWidth = aTheMask->GetWidth();
|
||||
mAlphaHeight = aTheMask->GetWidth();
|
||||
num = mAlphaWidth*mAlphaHeight;
|
||||
mARowBytes = aTheMask->GetLineStride();
|
||||
mAlphaBits = new unsigned char[mARowBytes * mAlphaHeight];
|
||||
|
||||
srcbits = aTheMask->GetBits();
|
||||
memcpy(mAlphaBits,srcbits,num);
|
||||
|
||||
return(PR_TRUE);
|
||||
}
|
||||
|
||||
return(PR_FALSE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRBool nsImageWin::CalcAlphaMetrics(nsIImage *aTheImage,nsPoint *aULLocation,PRInt32 *aNumlines,
|
||||
PRInt32 *aNumbytes,PRUint8 **aSImage,PRUint8 **aDImage,
|
||||
PRUint8 **aMImage,PRInt32 *aSLSpan,PRInt32 *aDLSpan,PRInt32 *aMLSpan)
|
||||
{
|
||||
PRBool doalpha = PR_FALSE;
|
||||
nsRect arect,srect,drect,irect;
|
||||
PRInt32 startx,starty,x,y;
|
||||
PRUint8 *alphabits;
|
||||
|
||||
if( IsOptimized() )
|
||||
return doalpha;
|
||||
|
||||
alphabits = aTheImage->GetAlphaBits();
|
||||
if(alphabits)
|
||||
{
|
||||
arect.SetRect(0,0,this->GetWidth(),this->GetHeight());
|
||||
srect.SetRect(aTheImage->GetAlphaXLoc(),aTheImage->GetAlphaYLoc(),aTheImage->GetAlphaWidth(),aTheImage->GetAlphaHeight());
|
||||
arect.IntersectRect(arect,srect);
|
||||
}
|
||||
else
|
||||
{
|
||||
arect.SetRect(0, 0, this->GetWidth(), this->GetHeight());
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
srect.SetRect(aULLocation->x, aULLocation->y, aTheImage->GetWidth(), aTheImage->GetHeight());
|
||||
drect = arect;
|
||||
|
||||
if (irect.IntersectRect(srect, drect))
|
||||
{
|
||||
// calculate destination information
|
||||
*aDLSpan = this->GetLineStride();
|
||||
*aNumbytes = this->CalcBytesSpan(irect.width);
|
||||
*aNumlines = irect.height;
|
||||
startx = irect.x;
|
||||
starty = this->GetHeight() - (irect.y + irect.height);
|
||||
*aDImage = mImageBits + (starty * (*aDLSpan)) + (3 * startx);
|
||||
|
||||
// get the intersection relative to the source rectangle
|
||||
srect.SetRect(0, 0, aTheImage->GetWidth(), aTheImage->GetHeight());
|
||||
drect = irect;
|
||||
drect.MoveBy(-aULLocation->x, -aULLocation->y);
|
||||
|
||||
drect.IntersectRect(drect,srect);
|
||||
*aSLSpan = aTheImage->GetLineStride();
|
||||
startx = drect.x;
|
||||
starty = aTheImage->GetHeight() - (drect.y + drect.height);
|
||||
*aSImage = aTheImage->GetBits() + (starty * (*aSLSpan)) + (3 * startx);
|
||||
|
||||
// 24 bit
|
||||
doalpha = PR_TRUE;
|
||||
|
||||
if(alphabits)
|
||||
{
|
||||
*aMLSpan = aTheImage->GetAlphaLineStride();
|
||||
*aMImage = alphabits;
|
||||
}
|
||||
else
|
||||
{
|
||||
aMLSpan = 0;
|
||||
*aMImage = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return doalpha;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// this routine has to flip the y, since the bits are in bottom scan
|
||||
// line to top.
|
||||
void nsImageWin::Comp24to24(nsImageWin *aTheImage,nsPoint *aULLocation,nsBlendQuality aBlendQuality)
|
||||
{
|
||||
nsRect arect,srect,drect,irect;
|
||||
PRInt32 dlinespan,slinespan,mlinespan,numbytes,numlines;
|
||||
PRUint8 *alphabits,*s1,*d1,*m1;
|
||||
|
||||
if( IsOptimized() )
|
||||
return;
|
||||
|
||||
if(CalcAlphaMetrics(aTheImage,aULLocation,&numlines,&numbytes,&s1,&d1,&m1,&slinespan,&dlinespan,&mlinespan))
|
||||
{
|
||||
alphabits = aTheImage->GetAlphaBits();
|
||||
if(alphabits)
|
||||
{
|
||||
numbytes/=3; // since the mask is only 8 bits, this routine wants number of pixels
|
||||
Do24BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,aBlendQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
Do24Blend(128,numlines,numbytes,s1,d1,slinespan,dlinespan,aBlendQuality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// This routine can not be fast enough
|
||||
void
|
||||
nsImageWin::Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality)
|
||||
{
|
||||
PRUint8 *d1,*d2,*s1,*s2,*m1,*m2;
|
||||
PRInt32 x,y;
|
||||
PRUint32 val1,val2,temp1,numlines,xinc,yinc;
|
||||
PRInt32 sspan,dspan,mspan;
|
||||
|
||||
sspan = aSLSpan;
|
||||
dspan = aDLSpan;
|
||||
mspan = aMLSpan;
|
||||
|
||||
// now go thru the image and blend (remember, its bottom upwards)
|
||||
s1 = aSImage;
|
||||
d1 = aDImage;
|
||||
m1 = aMImage;
|
||||
|
||||
numlines = aNumlines;
|
||||
xinc = 1;
|
||||
yinc = 1;
|
||||
|
||||
for (y = 0; y < aNumlines; y++)
|
||||
{
|
||||
s2 = s1;
|
||||
d2 = d1;
|
||||
m2 = m1;
|
||||
|
||||
for(x=0;x<aNumbytes;x++)
|
||||
{
|
||||
val1 = (*m2);
|
||||
val2 = 255-val1;
|
||||
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
if(temp1>255)
|
||||
temp1 = 255;
|
||||
*d2 = (unsigned char)temp1;
|
||||
d2++;
|
||||
s2++;
|
||||
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
if(temp1>255)
|
||||
temp1 = 255;
|
||||
*d2 = (unsigned char)temp1;
|
||||
d2++;
|
||||
s2++;
|
||||
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
if(temp1>255)
|
||||
temp1 = 255;
|
||||
*d2 = (unsigned char)temp1;
|
||||
d2++;
|
||||
s2++;
|
||||
m2++;
|
||||
}
|
||||
s1 += sspan;
|
||||
d1 += dspan;
|
||||
m1 += mspan;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// This routine can not be fast enough
|
||||
void
|
||||
nsImageWin::Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality)
|
||||
{
|
||||
PRUint8 *d1,*d2,*s1,*s2;
|
||||
PRInt32 x,y,val1,val2,temp1,numlines,xinc,yinc;;
|
||||
|
||||
|
||||
// now go thru the image and blend (remember, its bottom upwards)
|
||||
s1 = aSImage;
|
||||
d1 = aDImage;
|
||||
|
||||
val1 = aBlendVal;
|
||||
val2 = 255-val1;
|
||||
|
||||
numlines = aNumlines;
|
||||
xinc = 1;
|
||||
yinc = 1;
|
||||
|
||||
for(y = 0; y < aNumlines; y++)
|
||||
{
|
||||
s2 = s1;
|
||||
d2 = d1;
|
||||
|
||||
for(x = 0; x < aNumbytes; x++)
|
||||
{
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
if(temp1>255)
|
||||
temp1 = 255;
|
||||
*d2 = (unsigned char)temp1;
|
||||
|
||||
d2++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
s1 += aSLSpan;
|
||||
d1 += aDLSpan;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
nsIImage*
|
||||
nsImageWin::DuplicateImage()
|
||||
{
|
||||
PRInt32 num,i;
|
||||
nsImageWin *theimage;
|
||||
|
||||
if( IsOptimized() )
|
||||
return nsnull;
|
||||
|
||||
theimage = new nsImageWin();
|
||||
|
||||
NS_ADDREF(theimage);
|
||||
|
||||
// get the header and copy it
|
||||
theimage->mBHead = (LPBITMAPINFOHEADER)new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * theimage->mNumPalleteColors];
|
||||
num = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * theimage->mNumPalleteColors;
|
||||
memcpy(theimage->mBHead,this->mBHead,num);
|
||||
|
||||
// set in compute metrics
|
||||
theimage->mSizeImage = this->mSizeImage;
|
||||
theimage->mRowBytes = this->mRowBytes;
|
||||
theimage->mColorTable = (PRUint8 *)theimage->mBHead + sizeof(BITMAPINFOHEADER);
|
||||
theimage->mNumBytesPixel = this->mNumBytesPixel;
|
||||
theimage->mNumPalleteColors = this->mNumPalleteColors;
|
||||
theimage->mAlphaDepth = this->mAlphaDepth;
|
||||
theimage->mARowBytes = this->mARowBytes;
|
||||
theimage->mAlphaWidth = this->mAlphaWidth;
|
||||
theimage->mAlphaHeight = this->mAlphaHeight;
|
||||
theimage->mLocation = this->mLocation;
|
||||
theimage->mIsOptimized = this->mIsOptimized;
|
||||
|
||||
// set up the memory
|
||||
num = sizeof(RGBQUAD) * mNumPalleteColors;
|
||||
if(num>0)
|
||||
memcpy(mColorTable,this->mColorTable,sizeof(RGBQUAD) * mNumPalleteColors);
|
||||
|
||||
// the bits of the image
|
||||
if(theimage->mSizeImage>0)
|
||||
{
|
||||
theimage->mImageBits = new unsigned char[theimage->mSizeImage];
|
||||
memcpy(theimage->mImageBits,this->mImageBits,theimage->mSizeImage);
|
||||
}
|
||||
else
|
||||
theimage->mImageBits = nsnull;
|
||||
|
||||
|
||||
// bits of the alpha mask
|
||||
num = theimage->mAlphaWidth*theimage->mAlphaHeight;
|
||||
if(num>0)
|
||||
{
|
||||
theimage->mAlphaBits = new unsigned char[num];
|
||||
memcpy(theimage->mImageBits,this->mImageBits,theimage->mSizeImage);
|
||||
}
|
||||
else
|
||||
theimage->mAlphaBits = nsnull;
|
||||
|
||||
theimage->mColorMap = new nsColorMap;
|
||||
if (theimage->mColorMap != nsnull)
|
||||
{
|
||||
theimage->mColorMap->NumColors = theimage->mNumPalleteColors;
|
||||
theimage->mColorMap->Index = new PRUint8[3 * theimage->mNumPalleteColors];
|
||||
memset(theimage->mColorMap->Index, 0, sizeof(PRUint8) * (3 * theimage->mNumPalleteColors));
|
||||
}
|
||||
|
||||
for(i = 0; i < theimage->mColorMap->NumColors; i++)
|
||||
{
|
||||
theimage->mColorMap->Index[(3 * i) + 2] = this->mColorMap->Index[(3 * i) + 2];
|
||||
theimage->mColorMap->Index[(3 * i) + 1] = this->mColorMap->Index[(3 * i) + 1];
|
||||
theimage->mColorMap->Index[(3 * i)] = this->mColorMap->Index[(3 * i)];
|
||||
}
|
||||
|
||||
theimage->MakePalette();
|
||||
|
||||
theimage->mHBitmap = nsnull;
|
||||
|
||||
return (theimage);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRBool nsImageWin::MakePalette()
|
||||
{
|
||||
// makes a logical palette (mHPalette) from the DIB's color table
|
||||
// this palette will be selected and realized prior to drawing the DIB
|
||||
|
||||
if (mNumPalleteColors == 0)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mHPalette != nsnull)
|
||||
::DeleteObject(mHPalette);
|
||||
|
||||
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) + mNumPalleteColors * sizeof(PALETTEENTRY)];
|
||||
pLogPal->palVersion = 0x300;
|
||||
pLogPal->palNumEntries = mNumPalleteColors;
|
||||
LPRGBQUAD pDibQuad = (LPRGBQUAD) mColorTable;
|
||||
|
||||
for (int i = 0; i < mNumPalleteColors; i++)
|
||||
{
|
||||
pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
|
||||
pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
|
||||
pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
|
||||
pLogPal->palPalEntry[i].peFlags = 0;
|
||||
pDibQuad++;
|
||||
}
|
||||
|
||||
mHPalette = ::CreatePalette(pLogPal);
|
||||
delete pLogPal;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRBool nsImageWin :: SetSystemPalette(HDC* aHdc)
|
||||
{
|
||||
PRInt32 nsyscol, npal, nument;
|
||||
|
||||
// if the DIB doesn't have a color table, we can use the system palette
|
||||
|
||||
if (mNumPalleteColors != 0)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!::GetDeviceCaps(aHdc, RASTERCAPS) & RC_PALETTE)
|
||||
return PR_FALSE;
|
||||
|
||||
nsyscol = ::GetDeviceCaps(aHdc, NUMCOLORS);
|
||||
npal = ::GetDeviceCaps(aHdc, SIZEPALETTE);
|
||||
nument = (npal == 0) ? nsyscol : npal;
|
||||
|
||||
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) + nument * sizeof(PALETTEENTRY)];
|
||||
|
||||
pLogPal->palVersion = 0x300;
|
||||
pLogPal->palNumEntries = nument;
|
||||
|
||||
::GetSystemPaletteEntries(aHdc, 0, nument, (LPPALETTEENTRY)((LPBYTE)pLogPal + 2 * sizeof(WORD)));
|
||||
|
||||
mHPalette = ::CreatePalette(pLogPal);
|
||||
|
||||
delete pLogPal;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// creates an optimized bitmap, or HBITMAP
|
||||
nsresult nsImageWin :: Optimize(nsDrawingSurface aSurface)
|
||||
{
|
||||
return NS_OK; // TAKE THIS OUT
|
||||
|
||||
HDC the_hdc = (HDC)aSurface;
|
||||
|
||||
if ((the_hdc != NULL) && !IsOptimized() && (mSizeImage > 0))
|
||||
{
|
||||
mHBitmap = ::CreateDIBitmap(the_hdc, mBHead, CBM_INIT, mImageBits, (LPBITMAPINFO)mBHead, DIB_RGB_COLORS);
|
||||
|
||||
mIsOptimized = PR_TRUE;
|
||||
CleanUp(PR_FALSE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// figure out how big our palette needs to be
|
||||
void nsImageWin :: ComputePaletteSize(PRIntn nBitCount)
|
||||
{
|
||||
switch (nBitCount)
|
||||
{
|
||||
case 8:
|
||||
mNumPalleteColors = 256;
|
||||
mNumBytesPixel = 1;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
mNumPalleteColors = 0;
|
||||
mNumBytesPixel = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
mNumPalleteColors = -1;
|
||||
mNumBytesPixel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRInt32 nsImageWin :: CalcBytesSpan(PRUint32 aWidth)
|
||||
{
|
||||
PRInt32 spanbytes;
|
||||
|
||||
spanbytes = (aWidth * mBHead->biBitCount) >> 5;
|
||||
|
||||
if (((PRUint32)mBHead->biWidth * mBHead->biBitCount) & 0x1F)
|
||||
spanbytes++;
|
||||
|
||||
spanbytes <<= 2;
|
||||
|
||||
return(spanbytes);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void nsImageWin :: ComputeMetrics()
|
||||
{
|
||||
mSizeImage = mBHead->biSizeImage;
|
||||
|
||||
if (mSizeImage == 0)
|
||||
{
|
||||
mRowBytes = CalcBytesSpan(mBHead->biWidth);
|
||||
mSizeImage = mRowBytes * mBHead->biHeight; // no compression
|
||||
}
|
||||
|
||||
// set the color table in the info header
|
||||
|
||||
mColorTable = (PRUint8 *)mBHead + sizeof(BITMAPINFOHEADER);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// clean up our memory
|
||||
void nsImageWin :: CleanUp(PRBool aCleanUpAll)
|
||||
{
|
||||
// this only happens when we need to clean up everything
|
||||
if (aCleanUpAll == PR_TRUE)
|
||||
{
|
||||
if (mAlphaBits != nsnull)
|
||||
delete [] mAlphaBits;
|
||||
|
||||
if (mHBitmap != nsnull)
|
||||
::DeleteObject(mHBitmap);
|
||||
|
||||
if(mBHead)
|
||||
{
|
||||
delete[] mBHead;
|
||||
mBHead = nsnull;
|
||||
}
|
||||
|
||||
mHBitmap = nsnull;
|
||||
|
||||
mAlphaBits = nsnull;
|
||||
mIsOptimized = PR_FALSE;
|
||||
|
||||
if (mImageBits != nsnull)
|
||||
{
|
||||
delete [] mImageBits;
|
||||
mImageBits = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if (mHPalette != nsnull)
|
||||
::DeleteObject(mHPalette);
|
||||
|
||||
// Should be an ISupports, so we can release
|
||||
if (mColorMap != nsnull)
|
||||
{
|
||||
if (mColorMap->Index != nsnull)
|
||||
delete [] mColorMap->Index;
|
||||
delete mColorMap;
|
||||
}
|
||||
|
||||
mColorTable = nsnull;
|
||||
mNumPalleteColors = -1;
|
||||
mNumBytesPixel = 0;
|
||||
mSizeImage = 0;
|
||||
mHPalette = nsnull;
|
||||
mImageBits = nsnull;
|
||||
mColorMap = nsnull;
|
||||
}
|
||||
205
mozilla/gfx/src/windows/nsImageWin.h
Normal file
205
mozilla/gfx/src/windows/nsImageWin.h
Normal file
@@ -0,0 +1,205 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsImageWin_h___
|
||||
#define nsImageWin_h___
|
||||
|
||||
#include <windows.h>
|
||||
#include "nsIImage.h"
|
||||
|
||||
class nsImageWin : public nsIImage
|
||||
{
|
||||
public:
|
||||
nsImageWin();
|
||||
~nsImageWin();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/**
|
||||
@see nsIImage.h
|
||||
*/
|
||||
virtual PRInt32 GetHeight() { return mBHead->biHeight; }
|
||||
virtual PRInt32 GetWidth() { return mBHead->biWidth; }
|
||||
virtual PRUint8* GetBits() { return mImageBits; }
|
||||
virtual PRInt32 GetLineStride() {return mRowBytes; }
|
||||
virtual PRBool Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
virtual PRBool Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
virtual nsColorMap* GetColorMap() {return mColorMap;}
|
||||
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
||||
virtual PRBool IsOptimized() { return mIsOptimized; }
|
||||
virtual nsresult Optimize(nsDrawingSurface aSurface);
|
||||
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
|
||||
virtual PRInt32 GetAlphaWidth() { return mAlphaWidth;}
|
||||
virtual PRInt32 GetAlphaHeight() {return mAlphaHeight;}
|
||||
virtual PRInt32 GetAlphaXLoc() {return mLocation.x;}
|
||||
virtual PRInt32 GetAlphaYLoc() {return mLocation.y;}
|
||||
virtual PRInt32 GetAlphaLineStride(){ return mARowBytes; }
|
||||
virtual void CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation,nsBlendQuality aQuality);
|
||||
virtual nsIImage* DuplicateImage();
|
||||
|
||||
/**
|
||||
* Return the header size of the Device Independent Bitmap(DIB).
|
||||
* @return size of header in bytes
|
||||
*/
|
||||
PRIntn GetSizeHeader(){return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * mNumPalleteColors;}
|
||||
|
||||
/**
|
||||
* Return the image size of the Device Independent Bitmap(DIB).
|
||||
* @return size of image in bytes
|
||||
*/
|
||||
PRIntn GetSizeImage(){ return mSizeImage; }
|
||||
|
||||
/**
|
||||
* Make a palette for the DIB.
|
||||
* @return true or false if the palette was created
|
||||
*/
|
||||
PRBool MakePalette();
|
||||
|
||||
/**
|
||||
* Set the for this pixelmap to the system palette.
|
||||
* @param aHdc is the DC to get the palette from to use
|
||||
* @return true or false if the palette was set
|
||||
*/
|
||||
PRBool SetSystemPalette(HDC* aHdc);
|
||||
|
||||
|
||||
/**
|
||||
* Set the palette for an HDC.
|
||||
* @param aHDC is the DC to set the palette to
|
||||
* @param bBackround tells if the DC is in the background
|
||||
* @return true or false if the palette was set
|
||||
*/
|
||||
PRUintn UsePalette(HDC* aHdc, PRBool bBackground = PR_FALSE);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the number of bytes spaned for this image for a given width
|
||||
* @param aWidth is the width to calculate the number of bytes for
|
||||
* @return the number of bytes in this span
|
||||
*/
|
||||
PRInt32 CalcBytesSpan(PRUint32 aWidth);
|
||||
|
||||
PRBool SetAlphaMask(nsIImage *aTheMask);
|
||||
|
||||
void MoveAlphaMask(PRInt32 aX, PRInt32 aY){mLocation.x=aX;mLocation.y=aY;}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Blend two 24 bit image arrays using an 8 bit alpha mask
|
||||
* @param aNumlines Number of lines to blend
|
||||
* @param aNumberBytes Number of bytes per line to blend
|
||||
* @param aSImage Pointer to beginning of the source bytes
|
||||
* @param aDImage Pointer to beginning of the destination bytes
|
||||
* @param aMImage Pointer to beginning of the mask bytes
|
||||
* @param aSLSpan number of bytes per line for the source bytes
|
||||
* @param aDLSpan number of bytes per line for the destination bytes
|
||||
* @param aMLSpan number of bytes per line for the Mask bytes
|
||||
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
|
||||
*/
|
||||
void Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
|
||||
PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality);
|
||||
|
||||
/**
|
||||
* Blend two 24 bit image arrays using a passed in blend value
|
||||
* @param aNumlines Number of lines to blend
|
||||
* @param aNumberBytes Number of bytes per line to blend
|
||||
* @param aSImage Pointer to beginning of the source bytes
|
||||
* @param aDImage Pointer to beginning of the destination bytes
|
||||
* @param aMImage Pointer to beginning of the mask bytes
|
||||
* @param aSLSpan number of bytes per line for the source bytes
|
||||
* @param aDLSpan number of bytes per line for the destination bytes
|
||||
* @param aMLSpan number of bytes per line for the Mask bytes
|
||||
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
|
||||
*/
|
||||
void Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
|
||||
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the information we need to do a blend
|
||||
* @param aNumlines Number of lines to blend
|
||||
* @param aNumberBytes Number of bytes per line to blend
|
||||
* @param aSImage Pointer to beginning of the source bytes
|
||||
* @param aDImage Pointer to beginning of the destination bytes
|
||||
* @param aMImage Pointer to beginning of the mask bytes
|
||||
* @param aSLSpan number of bytes per line for the source bytes
|
||||
* @param aDLSpan number of bytes per line for the destination bytes
|
||||
* @param aMLSpan number of bytes per line for the Mask bytes
|
||||
*/
|
||||
PRBool CalcAlphaMetrics(nsIImage *aTheImage,nsPoint *aULLocation,PRInt32 *aNumlines,
|
||||
PRInt32 *aNumbytes,PRUint8 **aSImage,PRUint8 **aDImage,
|
||||
PRUint8 **aMImage,PRInt32 *SLSpan,PRInt32 *aDLSpan,PRInt32 *aMLSpan);
|
||||
|
||||
|
||||
/**
|
||||
* Clean up the memory used nsImageWin.
|
||||
* @param aCleanUpAll if True, all the memory used will be released otherwise just clean up the DIB memory
|
||||
*/
|
||||
void CleanUp(PRBool aCleanUpAll);
|
||||
|
||||
/**
|
||||
* Calculate the amount of memory needed for the palette
|
||||
* @param aBitCount is the number of bits per pixel
|
||||
*/
|
||||
void ComputePaletteSize(PRIntn aBitCount);
|
||||
|
||||
/**
|
||||
* Composite a 24 bit image into another 24 bit image
|
||||
* @param aTheImage The image to blend into this image
|
||||
* @param aULLocation The upper left coordinate to place the passed in image
|
||||
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
|
||||
*/
|
||||
void Comp24to24(nsImageWin *aTheImage,nsPoint *aULLocation,nsBlendQuality aBlendQuality);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the amount of memory needed for the initialization of the pixelmap
|
||||
*/
|
||||
void ComputeMetrics();
|
||||
|
||||
PRUint8 PaletteMatch(PRUint8 r, PRUint8 g, PRUint8 b);
|
||||
|
||||
PRInt8 mNumBytesPixel; // number of bytes per pixel
|
||||
PRInt16 mNumPalleteColors; // either 8 or 0
|
||||
PRInt32 mSizeImage; // number of bytes
|
||||
PRInt32 mRowBytes; // number of bytes per row
|
||||
PRUint8 *mColorTable; // color table for the bitmap
|
||||
PRUint8 *mImageBits; // starting address of DIB bits
|
||||
PRBool mIsOptimized; // Have we turned our DIB into a GDI?
|
||||
nsColorMap *mColorMap; // Redundant with mColorTable, but necessary
|
||||
|
||||
// alpha layer members
|
||||
PRUint8 *mAlphaBits; // alpha layer if we made one
|
||||
PRInt8 mAlphaDepth; // alpha layer depth
|
||||
PRInt16 mARowBytes;
|
||||
PRInt16 mAlphaWidth; // alpha layer width
|
||||
PRInt16 mAlphaHeight; // alpha layer height
|
||||
nsPoint mLocation; // alpha mask location
|
||||
PRInt8 mImageCache; // place to save off the old image for fast animation
|
||||
|
||||
|
||||
// for Set/GetColorMap
|
||||
HPALETTE mHPalette;
|
||||
HBITMAP mHBitmap; // the GDI bitmap
|
||||
LPBITMAPINFOHEADER mBHead; // BITMAPINFOHEADER
|
||||
};
|
||||
|
||||
#endif
|
||||
947
mozilla/gfx/src/windows/nsRenderingContextWin.cpp
Normal file
947
mozilla/gfx/src/windows/nsRenderingContextWin.cpp
Normal file
@@ -0,0 +1,947 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsRenderingContextWin.h"
|
||||
#include <math.h>
|
||||
|
||||
class GraphicsState
|
||||
{
|
||||
public:
|
||||
GraphicsState();
|
||||
GraphicsState(GraphicsState &aState);
|
||||
~GraphicsState();
|
||||
|
||||
GraphicsState *mNext;
|
||||
nsTransform2D mMatrix;
|
||||
nsRect mLocalClip;
|
||||
nsRect mGlobalClip;
|
||||
HRGN mClipRegion;
|
||||
nscolor mBrushColor;
|
||||
HBRUSH mSolidBrush;
|
||||
nsIFontMetrics *mFontMetrics;
|
||||
HFONT mFont;
|
||||
nscolor mPenColor;
|
||||
HPEN mSolidPen;
|
||||
};
|
||||
|
||||
GraphicsState :: GraphicsState()
|
||||
{
|
||||
mNext = nsnull;
|
||||
mMatrix.SetToIdentity();
|
||||
mLocalClip.x = mLocalClip.y = mLocalClip.width = mLocalClip.height = 0;
|
||||
mGlobalClip = mLocalClip;
|
||||
mClipRegion = NULL;
|
||||
mBrushColor = NS_RGB(0, 0, 0);
|
||||
mSolidBrush = NULL;
|
||||
mFontMetrics = nsnull;
|
||||
mFont = NULL;
|
||||
mPenColor = NS_RGB(0, 0, 0);
|
||||
mSolidPen = NULL;
|
||||
}
|
||||
|
||||
GraphicsState :: GraphicsState(GraphicsState &aState) :
|
||||
mMatrix(&aState.mMatrix),
|
||||
mLocalClip(aState.mLocalClip),
|
||||
mGlobalClip(aState.mGlobalClip)
|
||||
{
|
||||
mNext = &aState;
|
||||
mClipRegion = NULL;
|
||||
mBrushColor = aState.mBrushColor;
|
||||
mSolidBrush = NULL;
|
||||
mFontMetrics = nsnull;
|
||||
mFont = NULL;
|
||||
mPenColor = aState.mPenColor;
|
||||
mSolidPen = NULL;
|
||||
}
|
||||
|
||||
GraphicsState :: ~GraphicsState()
|
||||
{
|
||||
if (NULL != mClipRegion)
|
||||
{
|
||||
::DeleteObject(mClipRegion);
|
||||
mClipRegion = NULL;
|
||||
}
|
||||
|
||||
if (NULL != mSolidBrush)
|
||||
{
|
||||
::DeleteObject(mSolidBrush);
|
||||
mSolidBrush = NULL;
|
||||
}
|
||||
|
||||
//don't delete this because it lives in the font metrics
|
||||
mFont = NULL;
|
||||
|
||||
if (NULL != mSolidPen)
|
||||
{
|
||||
::DeleteObject(mSolidPen);
|
||||
mSolidPen = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID);
|
||||
|
||||
nsRenderingContextWin :: nsRenderingContextWin()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mDC = NULL;
|
||||
mMainDC = NULL;
|
||||
mDCOwner = nsnull;
|
||||
mFontMetrics = nsnull;
|
||||
mFontCache = nsnull;
|
||||
mOrigSolidBrush = NULL;
|
||||
mBlackBrush = NULL;
|
||||
mOrigFont = NULL;
|
||||
mDefFont = NULL;
|
||||
mOrigSolidPen = NULL;
|
||||
mBlackPen = NULL;
|
||||
mCurrBrushColor = NULL;
|
||||
mCurrFontMetrics = nsnull;
|
||||
mCurrPenColor = NULL;
|
||||
mNullPen = NULL;
|
||||
#ifdef NS_DEBUG
|
||||
mInitialized = PR_FALSE;
|
||||
#endif
|
||||
|
||||
mStateCache = new nsVoidArray();
|
||||
|
||||
//create an initial GraphicsState
|
||||
|
||||
PushState();
|
||||
|
||||
mP2T = 1.0f;
|
||||
}
|
||||
|
||||
nsRenderingContextWin :: ~nsRenderingContextWin()
|
||||
{
|
||||
NS_IF_RELEASE(mContext);
|
||||
NS_IF_RELEASE(mFontMetrics);
|
||||
NS_IF_RELEASE(mFontCache);
|
||||
|
||||
//destroy the initial GraphicsState
|
||||
|
||||
PopState();
|
||||
|
||||
//cleanup the DC so that we can just destroy objects
|
||||
//in the graphics state without worrying that we are
|
||||
//ruining the dc
|
||||
|
||||
if (NULL != mDC)
|
||||
{
|
||||
if (NULL != mOrigSolidBrush)
|
||||
{
|
||||
::SelectObject(mDC, mOrigSolidBrush);
|
||||
mOrigSolidBrush = NULL;
|
||||
}
|
||||
|
||||
if (NULL != mOrigFont)
|
||||
{
|
||||
::SelectObject(mDC, mOrigFont);
|
||||
mOrigFont = NULL;
|
||||
}
|
||||
|
||||
if (NULL != mDefFont)
|
||||
{
|
||||
::DeleteObject(mDefFont);
|
||||
mDefFont = NULL;
|
||||
}
|
||||
|
||||
if (NULL != mOrigSolidPen)
|
||||
{
|
||||
::SelectObject(mDC, mOrigSolidPen);
|
||||
mOrigSolidPen = NULL;
|
||||
}
|
||||
|
||||
if (NULL != mCurrBrush)
|
||||
::DeleteObject(mCurrBrush);
|
||||
|
||||
if ((NULL != mBlackBrush) && (mBlackBrush != mCurrBrush))
|
||||
::DeleteObject(mBlackBrush);
|
||||
|
||||
mCurrBrush = NULL;
|
||||
mBlackBrush = NULL;
|
||||
|
||||
//don't kill the font because the font cache/metrics owns it
|
||||
mCurrFont = NULL;
|
||||
|
||||
if (NULL != mCurrPen)
|
||||
::DeleteObject(mCurrPen);
|
||||
|
||||
if ((NULL != mBlackPen) && (mBlackPen != mCurrPen))
|
||||
::DeleteObject(mBlackPen);
|
||||
|
||||
if ((NULL != mNullPen) && (mNullPen != mCurrPen))
|
||||
::DeleteObject(mNullPen);
|
||||
|
||||
mCurrPen = NULL;
|
||||
mBlackPen = NULL;
|
||||
mNullPen = NULL;
|
||||
}
|
||||
|
||||
if (nsnull != mStateCache)
|
||||
{
|
||||
PRInt32 cnt = mStateCache->Count();
|
||||
|
||||
while (--cnt >= 0)
|
||||
{
|
||||
GraphicsState *state = (GraphicsState *)mStateCache->ElementAt(cnt);
|
||||
mStateCache->RemoveElementAt(cnt);
|
||||
|
||||
if (nsnull != state)
|
||||
delete state;
|
||||
}
|
||||
|
||||
delete mStateCache;
|
||||
mStateCache = nsnull;
|
||||
}
|
||||
|
||||
if (nsnull != mDCOwner)
|
||||
{
|
||||
//first try to get rid of a DC originally associated with the window
|
||||
//but pushed over to a dest DC for offscreen rendering. if there is no
|
||||
//rolled over DC, then the mDC is the one associated with the window.
|
||||
|
||||
if (nsnull != mMainDC)
|
||||
ReleaseDC((HWND)mDCOwner->GetNativeData(NS_NATIVE_WINDOW), mMainDC);
|
||||
else if (nsnull != mDC)
|
||||
ReleaseDC((HWND)mDCOwner->GetNativeData(NS_NATIVE_WINDOW), mDC);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mDCOwner);
|
||||
|
||||
mTMatrix = nsnull;
|
||||
mDC = NULL;
|
||||
mMainDC = NULL;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(nsRenderingContextWin, kRenderingContextIID)
|
||||
NS_IMPL_ADDREF(nsRenderingContextWin)
|
||||
NS_IMPL_RELEASE(nsRenderingContextWin)
|
||||
|
||||
nsresult nsRenderingContextWin :: Init(nsIDeviceContext* aContext,
|
||||
nsIWidget *aWindow)
|
||||
{
|
||||
NS_PRECONDITION(PR_FALSE == mInitialized, "double init");
|
||||
|
||||
mContext = aContext;
|
||||
NS_IF_ADDREF(mContext);
|
||||
|
||||
mDC = (HWND)aWindow->GetNativeData(NS_NATIVE_GRAPHIC);
|
||||
mDCOwner = aWindow;
|
||||
|
||||
if (mDCOwner)
|
||||
NS_ADDREF(mDCOwner);
|
||||
|
||||
return CommonInit();
|
||||
}
|
||||
|
||||
nsresult nsRenderingContextWin :: Init(nsIDeviceContext* aContext,
|
||||
nsDrawingSurface aSurface)
|
||||
{
|
||||
NS_PRECONDITION(PR_FALSE == mInitialized, "double init");
|
||||
|
||||
mContext = aContext;
|
||||
NS_IF_ADDREF(mContext);
|
||||
|
||||
mDC = (HDC)aSurface;
|
||||
mDCOwner = nsnull;
|
||||
|
||||
return CommonInit();
|
||||
}
|
||||
|
||||
nsresult nsRenderingContextWin :: CommonInit(void)
|
||||
{
|
||||
mTMatrix->AddScale(mContext->GetAppUnitsToDevUnits(),
|
||||
mContext->GetAppUnitsToDevUnits());
|
||||
mP2T = mContext->GetDevUnitsToAppUnits();
|
||||
mFontCache = mContext->GetFontCache();
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
mInitialized = PR_TRUE;
|
||||
#endif
|
||||
|
||||
mBlackBrush = ::CreateSolidBrush(RGB(0, 0, 0));
|
||||
mOrigSolidBrush = ::SelectObject(mDC, mBlackBrush);
|
||||
|
||||
mDefFont = ::CreateFont(12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
|
||||
ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY, FF_ROMAN | VARIABLE_PITCH, "Times New Roman");
|
||||
mOrigFont = ::SelectObject(mDC, mDefFont);
|
||||
|
||||
mBlackPen = ::CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
|
||||
mOrigSolidPen = ::SelectObject(mDC, mBlackPen);
|
||||
|
||||
mGammaTable = mContext->GetGammaTable();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsRenderingContextWin :: SelectOffScreenDrawingSurface(nsDrawingSurface aSurface)
|
||||
{
|
||||
mMainDC = mDC;
|
||||
mDC = (HDC)aSurface;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: Reset()
|
||||
{
|
||||
}
|
||||
|
||||
nsIDeviceContext * nsRenderingContextWin :: GetDeviceContext(void)
|
||||
{
|
||||
NS_IF_ADDREF(mContext);
|
||||
return mContext;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: PushState()
|
||||
{
|
||||
PRInt32 cnt = mStateCache->Count();
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
if (nsnull == mStates)
|
||||
mStates = new GraphicsState();
|
||||
else
|
||||
mStates = new GraphicsState(*mStates);
|
||||
}
|
||||
else
|
||||
{
|
||||
GraphicsState *state = (GraphicsState *)mStateCache->ElementAt(cnt - 1);
|
||||
mStateCache->RemoveElementAt(cnt - 1);
|
||||
|
||||
state->mNext = mStates;
|
||||
|
||||
//clone state info
|
||||
|
||||
state->mMatrix = mStates->mMatrix;
|
||||
state->mLocalClip = mStates->mLocalClip;
|
||||
state->mGlobalClip = mStates->mGlobalClip;
|
||||
state->mClipRegion = nsnull;
|
||||
state->mBrushColor = mStates->mBrushColor;
|
||||
state->mSolidBrush = nsnull;
|
||||
state->mFontMetrics = mStates->mFontMetrics;
|
||||
state->mFont = nsnull;
|
||||
state->mPenColor = mStates->mPenColor;
|
||||
state->mSolidPen = nsnull;
|
||||
|
||||
mStates = state;
|
||||
}
|
||||
|
||||
mTMatrix = &mStates->mMatrix;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: PopState()
|
||||
{
|
||||
if (nsnull == mStates)
|
||||
{
|
||||
NS_ASSERTION(!(nsnull == mStates), "state underflow");
|
||||
}
|
||||
else
|
||||
{
|
||||
GraphicsState *oldstate = mStates;
|
||||
|
||||
mStates = mStates->mNext;
|
||||
|
||||
mStateCache->AppendElement(oldstate);
|
||||
|
||||
if (nsnull != mStates)
|
||||
{
|
||||
mTMatrix = &mStates->mMatrix;
|
||||
|
||||
GraphicsState *pstate;
|
||||
|
||||
if (NULL != oldstate->mClipRegion)
|
||||
{
|
||||
pstate = mStates;
|
||||
|
||||
//the clip rect has changed from state to state, so
|
||||
//install the previous clip rect
|
||||
|
||||
while ((nsnull != pstate) && (NULL == pstate->mClipRegion))
|
||||
pstate = pstate->mNext;
|
||||
|
||||
if ((nsnull != pstate) && (pstate->mGlobalClip != oldstate->mGlobalClip))
|
||||
::SelectClipRgn(mDC, pstate->mClipRegion);
|
||||
else
|
||||
::SelectClipRgn(mDC, NULL);
|
||||
|
||||
//kill the clip region we are popping off the stack
|
||||
|
||||
::DeleteObject(oldstate->mClipRegion);
|
||||
oldstate->mClipRegion = NULL;
|
||||
}
|
||||
|
||||
oldstate->mSolidBrush = NULL;
|
||||
oldstate->mFont = NULL;
|
||||
oldstate->mSolidPen = NULL;
|
||||
}
|
||||
else
|
||||
mTMatrix = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsRenderingContextWin :: IsVisibleRect(const nsRect& aRect)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, PRBool aIntersect)
|
||||
{
|
||||
nsRect trect = aRect;
|
||||
|
||||
mStates->mLocalClip = aRect;
|
||||
|
||||
mTMatrix->TransformCoord(&trect.x, &trect.y,
|
||||
&trect.width, &trect.height);
|
||||
|
||||
//should we combine the new rect with the previous?
|
||||
|
||||
if (aIntersect == PR_TRUE)
|
||||
{
|
||||
if (PR_FALSE == mStates->mGlobalClip.IntersectRect(mStates->mGlobalClip, trect))
|
||||
{
|
||||
mStates->mGlobalClip.x = mStates->mGlobalClip.y = mStates->mGlobalClip.width = mStates->mGlobalClip.height = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
mStates->mGlobalClip = trect;
|
||||
|
||||
if (NULL != mStates->mClipRegion)
|
||||
::DeleteObject(mStates->mClipRegion);
|
||||
|
||||
mStates->mClipRegion = ::CreateRectRgn(mStates->mGlobalClip.x,
|
||||
mStates->mGlobalClip.y,
|
||||
mStates->mGlobalClip.XMost(),
|
||||
mStates->mGlobalClip.YMost());
|
||||
::SelectClipRgn(mDC, mStates->mClipRegion);
|
||||
}
|
||||
|
||||
const nsRect& nsRenderingContextWin :: GetClipRect()
|
||||
{
|
||||
return mStates->mLocalClip;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: SetColor(nscolor aColor)
|
||||
{
|
||||
mCurrentColor = aColor;
|
||||
mColor = RGB(mGammaTable[NS_GET_R(aColor)],
|
||||
mGammaTable[NS_GET_G(aColor)],
|
||||
mGammaTable[NS_GET_B(aColor)]);
|
||||
}
|
||||
|
||||
nscolor nsRenderingContextWin :: GetColor() const
|
||||
{
|
||||
return mCurrentColor;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: SetFont(const nsFont& aFont)
|
||||
{
|
||||
NS_IF_RELEASE(mFontMetrics);
|
||||
mFontMetrics = mFontCache->GetMetricsFor(aFont);
|
||||
}
|
||||
|
||||
const nsFont& nsRenderingContextWin :: GetFont()
|
||||
{
|
||||
return mFontMetrics->GetFont();
|
||||
}
|
||||
|
||||
nsIFontMetrics* nsRenderingContextWin :: GetFontMetrics()
|
||||
{
|
||||
return mFontMetrics;
|
||||
}
|
||||
|
||||
// add the passed in translation to the current translation
|
||||
void nsRenderingContextWin :: Translate(nscoord aX, nscoord aY)
|
||||
{
|
||||
mTMatrix->AddTranslation((float)aX,(float)aY);
|
||||
}
|
||||
|
||||
// add the passed in scale to the current scale
|
||||
void nsRenderingContextWin :: Scale(float aSx, float aSy)
|
||||
{
|
||||
mTMatrix->AddScale(aSx, aSy);
|
||||
}
|
||||
|
||||
nsTransform2D * nsRenderingContextWin :: GetCurrentTransform()
|
||||
{
|
||||
return mTMatrix;
|
||||
}
|
||||
|
||||
nsDrawingSurface nsRenderingContextWin :: CreateDrawingSurface(nsRect *aBounds)
|
||||
{
|
||||
HDC hDC = ::CreateCompatibleDC(mDC);
|
||||
|
||||
if (nsnull != aBounds)
|
||||
{
|
||||
HBITMAP hBits = ::CreateCompatibleBitmap(mDC, aBounds->width, aBounds->height);
|
||||
::SelectObject(hDC, hBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
HBITMAP hBits = ::CreateCompatibleBitmap(mDC, 2, 2);
|
||||
::SelectObject(hDC, hBits);
|
||||
}
|
||||
|
||||
return hDC;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DestroyDrawingSurface(nsDrawingSurface aDS)
|
||||
{
|
||||
HDC hDC = (HDC)aDS;
|
||||
|
||||
HBITMAP hTempBits = ::CreateCompatibleBitmap(hDC, 2, 2);
|
||||
HBITMAP hBits = ::SelectObject(hDC, hTempBits);
|
||||
|
||||
if (nsnull != hBits)
|
||||
::DeleteObject(hBits);
|
||||
|
||||
::DeleteObject(hTempBits);
|
||||
::DeleteDC(hDC);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1)
|
||||
{
|
||||
mTMatrix->TransformCoord(&aX0,&aY0);
|
||||
mTMatrix->TransformCoord(&aX1,&aY1);
|
||||
|
||||
SetupSolidPen();
|
||||
|
||||
::MoveToEx(mDC, (int)(aX0), (int)(aY0), NULL);
|
||||
::LineTo(mDC, (int)(aX1), (int)(aY1));
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawRect(const nsRect& aRect)
|
||||
{
|
||||
RECT nr;
|
||||
nsRect tr;
|
||||
|
||||
tr = aRect;
|
||||
mTMatrix->TransformCoord(&tr.x,&tr.y,&tr.width,&tr.height);
|
||||
nr.left = tr.x;
|
||||
nr.top = tr.y;
|
||||
nr.right = tr.x+tr.width;
|
||||
nr.bottom = tr.y+tr.height;
|
||||
|
||||
::FrameRect(mDC, &nr, SetupSolidBrush());
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
RECT nr;
|
||||
|
||||
mTMatrix->TransformCoord(&aX,&aY,&aWidth,&aHeight);
|
||||
nr.left = aX;
|
||||
nr.top = aY;
|
||||
nr.right = aX+aWidth;
|
||||
nr.bottom = aY+aHeight;
|
||||
|
||||
::FrameRect(mDC, &nr, SetupSolidBrush());
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: FillRect(const nsRect& aRect)
|
||||
{
|
||||
RECT nr;
|
||||
nsRect tr;
|
||||
|
||||
tr = aRect;
|
||||
mTMatrix->TransformCoord(&tr.x,&tr.y,&tr.width,&tr.height);
|
||||
nr.left = tr.x;
|
||||
nr.top = tr.y;
|
||||
nr.right = tr.x+tr.width;
|
||||
nr.bottom = tr.y+tr.height;
|
||||
|
||||
::FillRect(mDC, &nr, SetupSolidBrush());
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
RECT nr;
|
||||
nsRect tr;
|
||||
|
||||
mTMatrix->TransformCoord(&aX,&aY,&aWidth,&aHeight);
|
||||
nr.left = aX;
|
||||
nr.top = aY;
|
||||
nr.right = aX+aWidth;
|
||||
nr.bottom = aY+aHeight;
|
||||
|
||||
::FillRect(mDC, &nr, SetupSolidBrush());
|
||||
}
|
||||
|
||||
void nsRenderingContextWin::DrawPolygon(nsPoint aPoints[], PRInt32 aNumPoints)
|
||||
{
|
||||
// First transform nsPoint's into POINT's; perform coordinate space
|
||||
// transformation at the same time
|
||||
POINT pts[20];
|
||||
POINT* pp0 = pts;
|
||||
|
||||
if (aNumPoints > 20)
|
||||
pp0 = new POINT[aNumPoints];
|
||||
|
||||
POINT* pp = pp0;
|
||||
const nsPoint* np = &aPoints[0];
|
||||
|
||||
for (PRInt32 i = 0; i < aNumPoints; i++, pp++, np++)
|
||||
{
|
||||
pp->x = np->x;
|
||||
pp->y = np->y;
|
||||
mTMatrix->TransformCoord((int*)&pp->x,(int*)&pp->y);
|
||||
}
|
||||
|
||||
// Outline the polygon
|
||||
int pfm = ::GetPolyFillMode(mDC);
|
||||
::SetPolyFillMode(mDC, WINDING);
|
||||
LOGBRUSH lb;
|
||||
lb.lbStyle = BS_NULL;
|
||||
lb.lbColor = 0;
|
||||
lb.lbHatch = 0;
|
||||
SetupSolidPen();
|
||||
HBRUSH brush = ::CreateBrushIndirect(&lb);
|
||||
HBRUSH oldBrush = ::SelectObject(mDC, brush);
|
||||
::Polygon(mDC, pp0, int(aNumPoints));
|
||||
::SelectObject(mDC, oldBrush);
|
||||
::DeleteObject(brush);
|
||||
::SetPolyFillMode(mDC, pfm);
|
||||
|
||||
// Release temporary storage if necessary
|
||||
if (pp0 != pts)
|
||||
delete pp0;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin::FillPolygon(nsPoint aPoints[], PRInt32 aNumPoints)
|
||||
{
|
||||
// First transform nsPoint's into POINT's; perform coordinate space
|
||||
// transformation at the same time
|
||||
|
||||
POINT pts[20];
|
||||
POINT* pp0 = pts;
|
||||
|
||||
if (aNumPoints > 20)
|
||||
pp0 = new POINT[aNumPoints];
|
||||
|
||||
POINT* pp = pp0;
|
||||
const nsPoint* np = &aPoints[0];
|
||||
|
||||
for (PRInt32 i = 0; i < aNumPoints; i++, pp++, np++)
|
||||
{
|
||||
pp->x = np->x;
|
||||
pp->y = np->y;
|
||||
mTMatrix->TransformCoord((int*)&pp->x,(int*)&pp->y);
|
||||
}
|
||||
|
||||
// Fill the polygon
|
||||
int pfm = ::GetPolyFillMode(mDC);
|
||||
::SetPolyFillMode(mDC, WINDING);
|
||||
SetupSolidBrush();
|
||||
|
||||
if (NULL == mNullPen)
|
||||
mNullPen = ::CreatePen(PS_NULL, 0, 0);
|
||||
|
||||
HPEN oldPen = ::SelectObject(mDC, mNullPen);
|
||||
::Polygon(mDC, pp0, int(aNumPoints));
|
||||
::SelectObject(mDC, oldPen);
|
||||
::SetPolyFillMode(mDC, pfm);
|
||||
|
||||
// Release temporary storage if necessary
|
||||
if (pp0 != pts)
|
||||
delete pp0;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawEllipse(const nsRect& aRect)
|
||||
{
|
||||
DrawEllipse(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
mTMatrix->TransformCoord(&aX, &aY, &aWidth, &aHeight);
|
||||
|
||||
SetupSolidPen();
|
||||
HBRUSH oldBrush = ::SelectObject(mDC, ::GetStockObject(NULL_BRUSH));
|
||||
|
||||
::Ellipse(mDC, aX, aY, aX + aWidth, aY + aHeight);
|
||||
::SelectObject(mDC, oldBrush);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: FillEllipse(const nsRect& aRect)
|
||||
{
|
||||
FillEllipse(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
mTMatrix->TransformCoord(&aX, &aY, &aWidth, &aHeight);
|
||||
|
||||
SetupSolidPen();
|
||||
SetupSolidBrush();
|
||||
|
||||
::Ellipse(mDC, aX, aY, aX + aWidth, aY + aHeight);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawArc(const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle)
|
||||
{
|
||||
this->DrawArc(aRect.x,aRect.y,aRect.width,aRect.height,aStartAngle,aEndAngle);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle)
|
||||
{
|
||||
PRInt32 quad1, quad2, sx, sy, ex, ey, cx, cy;
|
||||
float anglerad, distance;
|
||||
|
||||
mTMatrix->TransformCoord(&aX, &aY, &aWidth, &aHeight);
|
||||
|
||||
SetupSolidPen();
|
||||
SetupSolidBrush();
|
||||
|
||||
// figure out the the coordinates of the arc from the angle
|
||||
distance = (float)sqrt((float)(aWidth * aWidth + aHeight * aHeight));
|
||||
cx = aX + aWidth / 2;
|
||||
cy = aY + aHeight / 2;
|
||||
|
||||
anglerad = (float)(aStartAngle / (180.0 / 3.14159265358979323846));
|
||||
quad1 = (PRInt32)(aStartAngle / 90.0);
|
||||
sx = (PRInt32)(distance * cos(anglerad) + cx);
|
||||
sy = (PRInt32)(cy - distance * sin(anglerad));
|
||||
|
||||
anglerad = (float)(aEndAngle / (180.0 / 3.14159265358979323846));
|
||||
quad2 = (PRInt32)(aEndAngle / 90.0);
|
||||
ex = (PRInt32)(distance * cos(anglerad) + cx);
|
||||
ey = (PRInt32)(cy - distance * sin(anglerad));
|
||||
|
||||
// this just makes it consitent, on windows 95 arc will always draw CC, nt this sets direction
|
||||
::SetArcDirection(mDC, AD_COUNTERCLOCKWISE);
|
||||
|
||||
::Arc(mDC, aX, aY, aX + aWidth, aY + aHeight, sx, sy, ex, ey);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: FillArc(const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle)
|
||||
{
|
||||
this->FillArc(aRect.x, aRect.y, aRect.width, aRect.height, aStartAngle, aEndAngle);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle)
|
||||
{
|
||||
PRInt32 quad1, quad2, sx, sy, ex, ey, cx, cy;
|
||||
float anglerad, distance;
|
||||
|
||||
mTMatrix->TransformCoord(&aX, &aY, &aWidth, &aHeight);
|
||||
|
||||
SetupSolidPen();
|
||||
SetupSolidBrush();
|
||||
|
||||
// figure out the the coordinates of the arc from the angle
|
||||
distance = (float)sqrt((float)(aWidth * aWidth + aHeight * aHeight));
|
||||
cx = aX + aWidth / 2;
|
||||
cy = aY + aHeight / 2;
|
||||
|
||||
anglerad = (float)(aStartAngle / (180.0 / 3.14159265358979323846));
|
||||
quad1 = (PRInt32)(aStartAngle / 90.0);
|
||||
sx = (PRInt32)(distance * cos(anglerad) + cx);
|
||||
sy = (PRInt32)(cy - distance * sin(anglerad));
|
||||
|
||||
anglerad = (float)(aEndAngle / (180.0 / 3.14159265358979323846));
|
||||
quad2 = (PRInt32)(aEndAngle / 90.0);
|
||||
ex = (PRInt32)(distance * cos(anglerad) + cx);
|
||||
ey = (PRInt32)(cy - distance * sin(anglerad));
|
||||
|
||||
// this just makes it consitent, on windows 95 arc will always draw CC, nt this sets direction
|
||||
::SetArcDirection(mDC, AD_COUNTERCLOCKWISE);
|
||||
|
||||
::Pie(mDC, aX, aY, aX + aWidth, aY + aHeight, sx, sy, ex, ey);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
nscoord aWidth)
|
||||
{
|
||||
int oldBkMode = ::SetBkMode(mDC, TRANSPARENT);
|
||||
int x,y;
|
||||
|
||||
SetupFont();
|
||||
|
||||
COLORREF oldColor = ::SetTextColor(mDC, mColor);
|
||||
x = aX;
|
||||
y = aY;
|
||||
mTMatrix->TransformCoord(&x,&y);
|
||||
::TextOut(mDC,x,y,aString,aLength);
|
||||
|
||||
if (mFontMetrics->GetFont().decorations & NS_FONT_DECORATION_OVERLINE)
|
||||
DrawLine(aX, aY, aX + aWidth, aY);
|
||||
|
||||
::SetBkMode(mDC, oldBkMode);
|
||||
::SetTextColor(mDC, oldColor);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY, nscoord aWidth)
|
||||
{
|
||||
int x,y;
|
||||
int oldBkMode = ::SetBkMode(mDC, TRANSPARENT);
|
||||
|
||||
SetupFont();
|
||||
|
||||
COLORREF oldColor = ::SetTextColor(mDC, mColor);
|
||||
x = aX;
|
||||
y = aY;
|
||||
mTMatrix->TransformCoord(&x,&y);
|
||||
::TextOutW(mDC,x,y,aString,aLength);
|
||||
|
||||
if (mFontMetrics->GetFont().decorations & NS_FONT_DECORATION_OVERLINE)
|
||||
DrawLine(aX, aY, aX + aWidth, aY);
|
||||
|
||||
::SetBkMode(mDC, oldBkMode);
|
||||
::SetTextColor(mDC, oldColor);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawString(const nsString& aString,
|
||||
nscoord aX, nscoord aY, nscoord aWidth)
|
||||
{
|
||||
DrawString(aString.GetUnicode(), aString.Length(), aX, aY, aWidth);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawImage(nsIImage *aImage, nscoord aX, nscoord aY)
|
||||
{
|
||||
NS_PRECONDITION(PR_TRUE == mInitialized, "!initialized");
|
||||
|
||||
nscoord width, height;
|
||||
|
||||
width = NS_TO_INT_ROUND(mP2T * aImage->GetWidth());
|
||||
height = NS_TO_INT_ROUND(mP2T * aImage->GetHeight());
|
||||
|
||||
this->DrawImage(aImage, aX, aY, width, height);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawImage(nsIImage *aImage, nscoord aX, nscoord aY,
|
||||
nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
nsRect tr;
|
||||
|
||||
tr.x = aX;
|
||||
tr.y = aY;
|
||||
tr.width = aWidth;
|
||||
tr.height = aHeight;
|
||||
|
||||
this->DrawImage(aImage, tr);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect)
|
||||
{
|
||||
nsRect sr,dr;
|
||||
|
||||
sr = aSRect;
|
||||
mTMatrix->TransformCoord(&sr.x, &sr.y, &sr.width, &sr.height);
|
||||
|
||||
dr = aDRect;
|
||||
mTMatrix->TransformCoord(&dr.x, &dr.y, &dr.width, &dr.height);
|
||||
|
||||
((nsImageWin *)aImage)->Draw(*this, mDC, sr.x, sr.y, sr.width, sr.height, dr.x, dr.y, dr.width, dr.height);
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: DrawImage(nsIImage *aImage, const nsRect& aRect)
|
||||
{
|
||||
nsRect tr;
|
||||
|
||||
tr = aRect;
|
||||
mTMatrix->TransformCoord(&tr.x, &tr.y, &tr.width, &tr.height);
|
||||
|
||||
((nsImageWin *)aImage)->Draw(*this, mDC, tr.x, tr.y, tr.width, tr.height);
|
||||
}
|
||||
|
||||
nsresult nsRenderingContextWin :: CopyOffScreenBits(nsRect &aBounds)
|
||||
{
|
||||
if ((nsnull != mDC) && (nsnull != mMainDC))
|
||||
{
|
||||
GraphicsState *pstate = mStates;
|
||||
|
||||
//look for a cliprect somewhere in the stack...
|
||||
|
||||
while ((nsnull != pstate) && (NULL == pstate->mClipRegion))
|
||||
pstate = pstate->mNext;
|
||||
|
||||
if (nsnull != pstate)
|
||||
::SelectClipRgn(mMainDC, pstate->mClipRegion);
|
||||
else
|
||||
::SelectClipRgn(mMainDC, NULL);
|
||||
|
||||
::BitBlt(mMainDC, 0, 0, aBounds.width, aBounds.height, mDC, 0, 0, SRCCOPY);
|
||||
}
|
||||
else
|
||||
NS_ASSERTION(0, "attempt to blit with bad DCs");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static numpen = 0;
|
||||
static numbrush = 0;
|
||||
static numfont = 0;
|
||||
|
||||
HBRUSH nsRenderingContextWin :: SetupSolidBrush(void)
|
||||
{
|
||||
if ((mCurrentColor != mCurrBrushColor) || (NULL == mCurrBrush))
|
||||
{
|
||||
HBRUSH tbrush = ::CreateSolidBrush(mColor);
|
||||
|
||||
::SelectObject(mDC, tbrush);
|
||||
|
||||
if (NULL != mCurrBrush)
|
||||
::DeleteObject(mCurrBrush);
|
||||
|
||||
mStates->mSolidBrush = mCurrBrush = tbrush;
|
||||
mStates->mBrushColor = mCurrBrushColor = mCurrentColor;
|
||||
//printf("brushes: %d\n", ++numbrush);
|
||||
}
|
||||
|
||||
return mCurrBrush;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: SetupFont(void)
|
||||
{
|
||||
if ((mFontMetrics != mCurrFontMetrics) || (NULL == mCurrFontMetrics))
|
||||
{
|
||||
HFONT tfont = (HFONT)mFontMetrics->GetFontHandle();
|
||||
|
||||
::SelectObject(mDC, tfont);
|
||||
|
||||
mStates->mFont = mCurrFont = tfont;
|
||||
mStates->mFontMetrics = mCurrFontMetrics = mFontMetrics;
|
||||
//printf("fonts: %d\n", ++numfont);
|
||||
}
|
||||
}
|
||||
|
||||
HPEN nsRenderingContextWin :: SetupSolidPen(void)
|
||||
{
|
||||
if ((mCurrentColor != mCurrPenColor) || (NULL == mCurrPen))
|
||||
{
|
||||
HPEN tpen = ::CreatePen(PS_SOLID, 0, mColor);
|
||||
|
||||
::SelectObject(mDC, tpen);
|
||||
|
||||
if (NULL != mCurrPen)
|
||||
::DeleteObject(mCurrPen);
|
||||
|
||||
mStates->mSolidPen = mCurrPen = tpen;
|
||||
mStates->mPenColor = mCurrPenColor = mCurrentColor;
|
||||
//printf("pens: %d\n", ++numpen);
|
||||
}
|
||||
|
||||
return mCurrPen;
|
||||
}
|
||||
168
mozilla/gfx/src/windows/nsRenderingContextWin.h
Normal file
168
mozilla/gfx/src/windows/nsRenderingContextWin.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsRenderingContextWin_h___
|
||||
#define nsRenderingContextWin_h___
|
||||
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsUnitConversion.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIFontCache.h"
|
||||
#include "nsImageWin.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
class GraphicsState;
|
||||
|
||||
class nsRenderingContextWin : public nsIRenderingContext
|
||||
{
|
||||
public:
|
||||
nsRenderingContextWin();
|
||||
~nsRenderingContextWin();
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
nsCRT::zero(rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(nsIDeviceContext* aContext, nsIWidget *aWindow);
|
||||
virtual nsresult Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface);
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
virtual nsIDeviceContext * GetDeviceContext(void);
|
||||
|
||||
virtual nsresult SelectOffScreenDrawingSurface(nsDrawingSurface aSurface);
|
||||
|
||||
virtual void PushState();
|
||||
virtual void PopState();
|
||||
|
||||
virtual PRBool IsVisibleRect(const nsRect& aRect);
|
||||
|
||||
virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect);
|
||||
virtual const nsRect& GetClipRect();
|
||||
|
||||
virtual void SetColor(nscolor aColor);
|
||||
virtual nscolor GetColor() const;
|
||||
|
||||
virtual void SetFont(const nsFont& aFont);
|
||||
virtual const nsFont& GetFont();
|
||||
|
||||
virtual nsIFontMetrics * GetFontMetrics();
|
||||
|
||||
virtual void Translate(nscoord aX, nscoord aY);
|
||||
virtual void Scale(float aSx, float aSy);
|
||||
virtual nsTransform2D * GetCurrentTransform();
|
||||
|
||||
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds);
|
||||
virtual void DestroyDrawingSurface(nsDrawingSurface aDS);
|
||||
|
||||
virtual void DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
|
||||
|
||||
virtual void DrawRect(const nsRect& aRect);
|
||||
virtual void DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
virtual void FillRect(const nsRect& aRect);
|
||||
virtual void FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
|
||||
virtual void DrawPolygon(nsPoint aPoints[], PRInt32 aNumPoints);
|
||||
virtual void FillPolygon(nsPoint aPoints[], PRInt32 aNumPoints);
|
||||
|
||||
virtual void DrawEllipse(const nsRect& aRect);
|
||||
virtual void DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
virtual void FillEllipse(const nsRect& aRect);
|
||||
virtual void FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
|
||||
virtual void DrawArc(const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle);
|
||||
virtual void DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle);
|
||||
virtual void FillArc(const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle);
|
||||
virtual void FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle);
|
||||
|
||||
virtual void DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
nscoord aWidth);
|
||||
virtual void DrawString(const PRUnichar *aString, PRUint32 aLength, nscoord aX, nscoord aY,
|
||||
nscoord aWidth);
|
||||
virtual void DrawString(const nsString& aString, nscoord aX, nscoord aY,
|
||||
nscoord aWidth);
|
||||
|
||||
virtual void DrawImage(nsIImage *aImage, nscoord aX, nscoord aY);
|
||||
virtual void DrawImage(nsIImage *aImage, nscoord aX, nscoord aY,
|
||||
nscoord aWidth, nscoord aHeight);
|
||||
virtual void DrawImage(nsIImage *aImage, const nsRect& aRect);
|
||||
virtual void DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect);
|
||||
|
||||
virtual nsresult CopyOffScreenBits(nsRect &aBounds);
|
||||
|
||||
private:
|
||||
nsresult CommonInit(void);
|
||||
HBRUSH SetupSolidBrush(void);
|
||||
HPEN SetupSolidPen(void);
|
||||
void SetupFont(void);
|
||||
|
||||
protected:
|
||||
nscolor mCurrentColor;
|
||||
nsTransform2D *mTMatrix; // transform that all the graphics drawn here will obey
|
||||
nsIFontMetrics *mFontMetrics;
|
||||
nsIFontCache *mFontCache;
|
||||
HDC mDC;
|
||||
COLORREF mColor;
|
||||
nsIWidget *mDCOwner;
|
||||
// int mOldMapMode;
|
||||
nsIDeviceContext *mContext;
|
||||
float mP2T;
|
||||
HDC mMainDC;
|
||||
//default objects
|
||||
HBRUSH mOrigSolidBrush;
|
||||
HBRUSH mBlackBrush;
|
||||
HFONT mOrigFont;
|
||||
HFONT mDefFont;
|
||||
HPEN mOrigSolidPen;
|
||||
HPEN mBlackPen;
|
||||
//state management
|
||||
GraphicsState *mStates;
|
||||
nsVoidArray *mStateCache;
|
||||
nscolor mCurrBrushColor;
|
||||
HBRUSH mCurrBrush;
|
||||
nsIFontMetrics *mCurrFontMetrics;
|
||||
HFONT mCurrFont;
|
||||
nscolor mCurrPenColor;
|
||||
HPEN mCurrPen;
|
||||
HPEN mNullPen;
|
||||
PRUint8 *mGammaTable;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRBool mInitialized;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* nsRenderingContextWin_h___ */
|
||||
32
mozilla/gfx/tests/DumpColors.cpp
Normal file
32
mozilla/gfx/tests/DumpColors.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsColor.h"
|
||||
#include "nsColorNames.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const nsColorNames::NameTableEntry* et = &nsColorNames::kNameTable[0];
|
||||
for (int i = 0; i < COLOR_MAX; i++, et++) {
|
||||
nscolor rgba = nsColorNames::kColors[i];
|
||||
printf("%s: NS_RGB(%d,%d,%d,%d)\n", et->name,
|
||||
NS_GET_R(rgba), NS_GET_G(rgba), NS_GET_B(rgba), NS_GET_A(rgba));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
63
mozilla/gfx/tests/Makefile
Normal file
63
mozilla/gfx/tests/Makefile
Normal file
@@ -0,0 +1,63 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=../..
|
||||
|
||||
DIRS = btest
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
CPPSRCS = \
|
||||
DumpColors.cpp \
|
||||
TestColorNames.cpp \
|
||||
TestRect.cpp \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES+=-I../src -I$(PUBLIC)/raptor -I$(PUBLIC)/xpcom
|
||||
|
||||
DIRS =
|
||||
|
||||
OBJS = $(CPPSRCS:.cpp=.o)
|
||||
|
||||
EX_LIBS = \
|
||||
$(DIST)/lib/libraptorgfx.a \
|
||||
$(DIST)/lib/libraptorbase.a \
|
||||
$(DIST)/lib/libxpcom.a \
|
||||
$(DIST)/lib/libplc21.a \
|
||||
$(DIST)/lib/libplds21.a \
|
||||
$(DIST)/lib/libnspr21.a \
|
||||
$(NULL)
|
||||
|
||||
PROGS = $(addprefix $(OBJDIR)/, $(CPPSRCS:.cpp=))
|
||||
|
||||
TARGETS = $(PROGS)
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CCC) -o $@ $(CFLAGS) -c $*.cpp
|
||||
|
||||
$(PROGS):$(OBJDIR)/%: $(OBJDIR)/%.o $(EX_LIBS)
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CCC) -o $@ $@.o $(LDFLAGS) $(EX_LIBS) $(OS_LIBS)
|
||||
|
||||
export::
|
||||
|
||||
install:: $(TARGETS)
|
||||
$(INSTALL) $(PROGS) $(DIST)/bin
|
||||
|
||||
114
mozilla/gfx/tests/TestColorNames.cpp
Normal file
114
mozilla/gfx/tests/TestColorNames.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "nsColorNames.h"
|
||||
#include "prprf.h"
|
||||
|
||||
static const char* kJunkNames[] = {
|
||||
nsnull,
|
||||
"",
|
||||
"123",
|
||||
"backgroundz",
|
||||
"zzzzzz",
|
||||
"#@$&@#*@*$@$#"
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
PRInt32 id;
|
||||
int rv = 0;
|
||||
|
||||
// First make sure we can find all of the tags that are supposed to
|
||||
// be in the table. Futz with the case to make sure any case will
|
||||
// work
|
||||
const nsColorNames::NameTableEntry* et = &nsColorNames::kNameTable[0];
|
||||
const nsColorNames::NameTableEntry* end = &nsColorNames::kNameTable[COLOR_MAX];
|
||||
while (et < end) {
|
||||
// Lookup color by name and make sure it has the right id
|
||||
char tagName[100];
|
||||
id = nsColorNames::LookupName(et->name);
|
||||
if (id < 0) {
|
||||
printf("bug: can't find '%s'\n", et->name);
|
||||
rv = -1;
|
||||
}
|
||||
if (et->id != id) {
|
||||
printf("bug: name='%s' et->id=%d id=%d\n", et->name, et->id, id);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
// fiddle with the case to make sure we can still find it
|
||||
strcpy(tagName, et->name);
|
||||
tagName[0] = tagName[0] - 32;
|
||||
id = nsColorNames::LookupName(tagName);
|
||||
if (id < 0) {
|
||||
printf("bug: can't find '%s'\n", tagName);
|
||||
rv = -1;
|
||||
}
|
||||
if (et->id != id) {
|
||||
printf("bug: name='%s' et->id=%d id=%d\n", et->name, et->id, id);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
// Check that color lookup by name gets the right rgb value
|
||||
nscolor rgb;
|
||||
if (!NS_ColorNameToRGB(et->name, &rgb)) {
|
||||
printf("bug: name='%s' didn't NS_ColorNameToRGB\n", et->name);
|
||||
rv = -1;
|
||||
}
|
||||
if (nsColorNames::kColors[et->id] != rgb) {
|
||||
printf("bug: name='%s' ColorNameToRGB=%x kColors[%d]=%x\n",
|
||||
et->name, rgb, nsColorNames::kColors[et->id]);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
// Check that parsing an RGB value in hex gets the right values
|
||||
PRUint8 r = NS_GET_R(rgb);
|
||||
PRUint8 g = NS_GET_G(rgb);
|
||||
PRUint8 b = NS_GET_B(rgb);
|
||||
char cbuf[50];
|
||||
PR_snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x", r, g, b);
|
||||
nscolor hexrgb;
|
||||
if (!NS_HexToRGB(cbuf, &hexrgb)) {
|
||||
printf("bug: hex conversion to color of '%s' failed\n", cbuf);
|
||||
rv = -1;
|
||||
}
|
||||
if (!NS_HexToRGB(cbuf + 1, &hexrgb)) {
|
||||
printf("bug: hex conversion to color of '%s' failed\n", cbuf);
|
||||
rv = -1;
|
||||
}
|
||||
if (hexrgb != rgb) {
|
||||
printf("bug: rgb=%x hexrgb=%x\n", rgb, hexrgb);
|
||||
rv = -1;
|
||||
}
|
||||
et++;
|
||||
}
|
||||
|
||||
// Now make sure we don't find some garbage
|
||||
for (int i = 0; i < sizeof(kJunkNames) / sizeof(const char*); i++) {
|
||||
const char* tag = kJunkNames[i];
|
||||
id = nsColorNames::LookupName(tag);
|
||||
if (id >= 0) {
|
||||
printf("bug: found '%s'\n", tag ? tag : "(null)");
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
431
mozilla/gfx/tests/TestRect.cpp
Normal file
431
mozilla/gfx/tests/TestRect.cpp
Normal file
@@ -0,0 +1,431 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsRect.h"
|
||||
#include <stdio.h>
|
||||
#ifdef XP_PC
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static PRBool
|
||||
TestConstructors()
|
||||
{
|
||||
// Create a rectangle
|
||||
nsRect rect1(10, 20, 30, 40);
|
||||
|
||||
// Make sure the rectangle was properly initialized
|
||||
if ((rect1.x != 10) || (rect1.y != 20) ||
|
||||
(rect1.width != 30) || (rect1.height != 40)) {
|
||||
printf("rect initialization failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Create a second rect using the copy constructor
|
||||
nsRect rect2(rect1);
|
||||
|
||||
// Make sure the rectangle was properly initialized
|
||||
if ((rect2.x != rect1.x) || (rect2.y != rect1.y) ||
|
||||
(rect2.width != rect1.width) || (rect2.height != rect1.height)) {
|
||||
printf("rect copy constructor failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
TestEqualityOperator()
|
||||
{
|
||||
nsRect rect1(10, 20, 30, 40);
|
||||
nsRect rect2(rect1);
|
||||
|
||||
// Test the equality operator
|
||||
if (!(rect1 == rect2)) {
|
||||
printf("rect equality operator failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test the inequality operator
|
||||
if (rect1 != rect2) {
|
||||
printf("rect inequality operator failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Make sure that two empty rects are equal
|
||||
rect1.Empty();
|
||||
rect2.Empty();
|
||||
if (!(rect1 == rect2)) {
|
||||
printf("rect equality operator failed for empty rects!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
TestContainment()
|
||||
{
|
||||
nsRect rect1(10, 10, 50, 50);
|
||||
|
||||
// Test the point containment methods
|
||||
//
|
||||
|
||||
// Basic test of a point in the middle of the rect
|
||||
if (!rect1.Contains(rect1.x + rect1.width/2, rect1.y + rect1.height/2)) {
|
||||
printf("point containment test #1 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test against a point at the left/top edges
|
||||
if (!rect1.Contains(rect1.x, rect1.y)) {
|
||||
printf("point containment test #2 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test against a point at the right/bottom extents
|
||||
if (rect1.Contains(rect1.XMost(), rect1.YMost())) {
|
||||
printf("point containment test #3 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test the rect containment methods
|
||||
//
|
||||
nsRect rect2(rect1);
|
||||
|
||||
// Test against a rect that's the same as rect1
|
||||
if (!rect1.Contains(rect2)) {
|
||||
printf("rect containment test #1 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test against a rect whose left edge (only) is outside of rect1
|
||||
rect2.x--;
|
||||
if (rect1.Contains(rect2)) {
|
||||
printf("rect containment test #2 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x++;
|
||||
|
||||
// Test against a rect whose top edge (only) is outside of rect1
|
||||
rect2.y--;
|
||||
if (rect1.Contains(rect2)) {
|
||||
printf("rect containment test #3 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y++;
|
||||
|
||||
// Test against a rect whose right edge (only) is outside of rect1
|
||||
rect2.x++;
|
||||
if (rect1.Contains(rect2)) {
|
||||
printf("rect containment test #2 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x--;
|
||||
|
||||
// Test against a rect whose bottom edge (only) is outside of rect1
|
||||
rect2.y++;
|
||||
if (rect1.Contains(rect2)) {
|
||||
printf("rect containment test #3 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y--;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Test the method that returns a boolean result but doesn't return a
|
||||
// a rectangle
|
||||
static PRBool
|
||||
TestIntersects()
|
||||
{
|
||||
nsRect rect1(10, 10, 50, 50);
|
||||
nsRect rect2(rect1);
|
||||
|
||||
// Test against a rect that's the same as rect1
|
||||
if (!rect1.Intersects(rect2)) {
|
||||
printf("rect intersects test #1 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test against a rect that's enclosed by rect1
|
||||
rect2.Deflate(1, 1);
|
||||
if (!rect1.Contains(rect2) || !rect1.Intersects(rect2)) {
|
||||
printf("rect intersects test #2 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.Inflate(1, 1);
|
||||
|
||||
// Make sure inflate and deflate worked correctly
|
||||
if (rect1 != rect2) {
|
||||
printf("rect inflate or deflate failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test against a rect that overlaps the left edge of rect1
|
||||
rect2.x--;
|
||||
if (!rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #3 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x++;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the left
|
||||
rect2.x -= rect2.width;
|
||||
if (rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #4 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x += rect2.width;
|
||||
|
||||
// Test against a rect that overlaps the top edge of rect1
|
||||
rect2.y--;
|
||||
if (!rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #5 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y++;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the top
|
||||
rect2.y -= rect2.height;
|
||||
if (rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #6 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y += rect2.height;
|
||||
|
||||
// Test against a rect that overlaps the right edge of rect1
|
||||
rect2.x++;
|
||||
if (!rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #7 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x--;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the right
|
||||
rect2.x += rect2.width;
|
||||
if (rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #8 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x -= rect2.width;
|
||||
|
||||
// Test against a rect that overlaps the bottom edge of rect1
|
||||
rect2.y++;
|
||||
if (!rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #9 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y--;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the bottom
|
||||
rect2.y += rect2.height;
|
||||
if (rect1.Intersects(rect2)) {
|
||||
printf("rect containment test #10 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y -= rect2.height;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Test the method that returns a boolean result and an intersection rect
|
||||
static PRBool
|
||||
TestIntersection()
|
||||
{
|
||||
nsRect rect1(10, 10, 50, 50);
|
||||
nsRect rect2(rect1);
|
||||
nsRect dest;
|
||||
|
||||
// Test against a rect that's the same as rect1
|
||||
if (!dest.IntersectRect(rect1, rect2) || (dest != rect1)) {
|
||||
printf("rect intersection test #1 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test against a rect that's enclosed by rect1
|
||||
rect2.Deflate(1, 1);
|
||||
if (!dest.IntersectRect(rect1, rect2) || (dest != rect2)) {
|
||||
printf("rect intersection test #2 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.Inflate(1, 1);
|
||||
|
||||
// Test against a rect that overlaps the left edge of rect1
|
||||
rect2.x--;
|
||||
if (!dest.IntersectRect(rect1, rect2) ||
|
||||
(dest != nsRect(rect1.x, rect1.y, rect1.width - 1, rect1.height))) {
|
||||
printf("rect intersection test #3 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x++;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the left
|
||||
rect2.x -= rect2.width;
|
||||
if (dest.IntersectRect(rect1, rect2)) {
|
||||
printf("rect intersection test #4 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
// Make sure an empty rect is returned
|
||||
if (!dest.IsEmpty()) {
|
||||
printf("rect intersection test #4 no empty rect!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x += rect2.width;
|
||||
|
||||
// Test against a rect that overlaps the top edge of rect1
|
||||
rect2.y--;
|
||||
if (!dest.IntersectRect(rect1, rect2) ||
|
||||
(dest != nsRect(rect1.x, rect1.y, rect1.width, rect1.height - 1))) {
|
||||
printf("rect intersection test #5 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y++;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the top
|
||||
rect2.y -= rect2.height;
|
||||
if (dest.IntersectRect(rect1, rect2)) {
|
||||
printf("rect intersection test #6 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
// Make sure an empty rect is returned
|
||||
if (!dest.IsEmpty()) {
|
||||
printf("rect intersection test #6 no empty rect!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y += rect2.height;
|
||||
|
||||
// Test against a rect that overlaps the right edge of rect1
|
||||
rect2.x++;
|
||||
if (!dest.IntersectRect(rect1, rect2) ||
|
||||
(dest != nsRect(rect1.x + 1, rect1.y, rect1.width - 1, rect1.height))) {
|
||||
printf("rect intersection test #7 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x--;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the right
|
||||
rect2.x += rect2.width;
|
||||
if (dest.IntersectRect(rect1, rect2)) {
|
||||
printf("rect intersection test #8 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
// Make sure an empty rect is returned
|
||||
if (!dest.IsEmpty()) {
|
||||
printf("rect intersection test #8 no empty rect!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.x -= rect2.width;
|
||||
|
||||
// Test against a rect that overlaps the bottom edge of rect1
|
||||
rect2.y++;
|
||||
if (!dest.IntersectRect(rect1, rect2) ||
|
||||
(dest != nsRect(rect1.x, rect1.y + 1, rect1.width, rect1.height - 1))) {
|
||||
printf("rect intersection test #9 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y--;
|
||||
|
||||
// Test against a rect that's outside of rect1 on the bottom
|
||||
rect2.y += rect2.height;
|
||||
if (dest.IntersectRect(rect1, rect2)) {
|
||||
printf("rect intersection test #10 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
// Make sure an empty rect is returned
|
||||
if (!dest.IsEmpty()) {
|
||||
printf("rect intersection test #10 no empty rect!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
rect2.y -= rect2.height;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
TestUnion()
|
||||
{
|
||||
nsRect rect1;
|
||||
nsRect rect2(10, 10, 50, 50);
|
||||
nsRect dest;
|
||||
|
||||
// Check the case where the receiver is an empty rect
|
||||
rect1.Empty();
|
||||
if (!dest.UnionRect(rect1, rect2) || (dest != rect2)) {
|
||||
printf("rect union test #1 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Check the case where the source rect is an empty rect
|
||||
rect1 = rect2;
|
||||
rect2.Empty();
|
||||
if (!dest.UnionRect(rect1, rect2) || (dest != rect1)) {
|
||||
printf("rect union test #2 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test the case where both rects are empty. This should fail
|
||||
rect1.Empty();
|
||||
rect2.Empty();
|
||||
if (dest.UnionRect(rect1, rect2)) {
|
||||
printf("rect union test #3 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test union case where the two rects don't overlap at all
|
||||
rect1.SetRect(10, 10, 50, 50);
|
||||
rect2.SetRect(100, 100, 50, 50);
|
||||
if (!dest.UnionRect(rect1, rect2) ||
|
||||
(dest != nsRect(rect1.x, rect1.y, rect2.XMost() - rect1.x, rect2.YMost() - rect1.y))) {
|
||||
printf("rect union test #4 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Test union case where the two rects overlap
|
||||
rect1.SetRect(30, 30, 50, 50);
|
||||
rect2.SetRect(10, 10, 50, 50);
|
||||
if (!dest.UnionRect(rect1, rect2) ||
|
||||
(dest != nsRect(rect2.x, rect2.y, rect1.XMost() - rect2.x, rect1.YMost() - rect2.y))) {
|
||||
printf("rect union test #5 failed!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (!TestConstructors())
|
||||
return -1;
|
||||
|
||||
if (!TestEqualityOperator())
|
||||
return -1;
|
||||
|
||||
if (!TestContainment())
|
||||
return -1;
|
||||
|
||||
if (!TestIntersects())
|
||||
return -1;
|
||||
|
||||
if (!TestIntersection())
|
||||
return -1;
|
||||
|
||||
if (!TestUnion())
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
982
mozilla/gfx/tests/btest/BitTest.cpp
Normal file
982
mozilla/gfx/tests/btest/BitTest.cpp
Normal file
@@ -0,0 +1,982 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
//we need openfilename stuff... MMP
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include "prtypes.h"
|
||||
#include <stdio.h>
|
||||
#include "resources.h"
|
||||
#include "nsIImageManager.h"
|
||||
#include "nsIImageGroup.h"
|
||||
#include "nsIImageRequest.h"
|
||||
#include "nsIImageObserver.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
|
||||
static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID);
|
||||
|
||||
static NS_DEFINE_IID(kCWindowIID, NS_WINDOW_CID);
|
||||
static NS_DEFINE_IID(kCChildWindowIID, NS_CHILD_CID);
|
||||
static NS_DEFINE_IID(kCScrollbarIID, NS_VERTSCROLLBAR_CID);
|
||||
|
||||
static char* class1Name = "ImageTest";
|
||||
|
||||
static HANDLE gInstance, gPrevInstance;
|
||||
static nsIImageManager *gImageManager = nsnull;
|
||||
static nsIImageGroup *gImageGroup = nsnull;
|
||||
static nsIImageRequest *gImageReq = nsnull;
|
||||
static HWND gHwnd;
|
||||
static nsIWidget *gWindow = nsnull;
|
||||
static nsIImage *gImage = nsnull;
|
||||
static nsIImage *gBlendImage = nsnull;
|
||||
static nsIImage *gMaskImage = nsnull;
|
||||
static PRBool gInstalledColorMap = PR_FALSE;
|
||||
static PRInt32 gXOff,gYOff,gTestNum;
|
||||
|
||||
extern void Compositetest(PRInt32 aTestNum,nsIImage *aImage,nsIImage *aBImage,nsIImage *aMImage, PRInt32 aX, PRInt32 aY);
|
||||
extern PRInt32 speedtest(nsIImage *aTheImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
extern PRInt32 drawtest(nsIRenderingContext *aSurface);
|
||||
extern PRInt32 filltest(nsIRenderingContext *aSurface);
|
||||
extern PRInt32 arctest(nsIRenderingContext *aSurface);
|
||||
extern PRBool IsImageLoaded();
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
||||
class MyBlendObserver : public nsIImageRequestObserver
|
||||
{
|
||||
private:
|
||||
nsIImage **mImage; // address of pointer to put info into
|
||||
|
||||
public:
|
||||
MyBlendObserver(nsIImage **aImage);
|
||||
~MyBlendObserver();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void Notify(nsIImageRequest *aImageRequest,nsIImage *aImage,
|
||||
nsImageNotification aNotificationType,
|
||||
PRInt32 aParam1, PRInt32 aParam2,void *aParam3);
|
||||
|
||||
virtual void NotifyError(nsIImageRequest *aImageRequest,nsImageError aErrorType);
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
MyBlendObserver::MyBlendObserver(nsIImage **aImage)
|
||||
{
|
||||
mImage = aImage;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
MyBlendObserver::~MyBlendObserver()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS(MyBlendObserver, kIImageObserverIID)
|
||||
|
||||
void
|
||||
MyBlendObserver::Notify(nsIImageRequest *aImageRequest,
|
||||
nsIImage *aImage,
|
||||
nsImageNotification aNotificationType,
|
||||
PRInt32 aParam1, PRInt32 aParam2,
|
||||
void *aParam3)
|
||||
{
|
||||
switch (aNotificationType)
|
||||
{
|
||||
case nsImageNotification_kDimensions:
|
||||
break;
|
||||
case nsImageNotification_kPixmapUpdate:
|
||||
case nsImageNotification_kImageComplete:
|
||||
case nsImageNotification_kFrameComplete:
|
||||
{
|
||||
if (*mImage == nsnull && aImage)
|
||||
{
|
||||
*mImage = aImage;
|
||||
NS_ADDREF(aImage);
|
||||
}
|
||||
|
||||
if ( gBlendImage && (aNotificationType == nsImageNotification_kImageComplete) )
|
||||
{
|
||||
nsColorMap *cmap = (*mImage)->GetColorMap();
|
||||
nsRect *rect = (nsRect *)aParam3;
|
||||
|
||||
Compositetest(gTestNum,gImage,gBlendImage,gMaskImage,gXOff,gYOff);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void
|
||||
MyBlendObserver::NotifyError(nsIImageRequest *aImageRequest,
|
||||
nsImageError aErrorType)
|
||||
{
|
||||
::MessageBox(NULL, "Blend Image loading error!",class1Name, MB_OK);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
class MyObserver : public nsIImageRequestObserver
|
||||
{
|
||||
public:
|
||||
MyObserver();
|
||||
~MyObserver();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void Notify(nsIImageRequest *aImageRequest,nsIImage *aImage,
|
||||
nsImageNotification aNotificationType,
|
||||
PRInt32 aParam1, PRInt32 aParam2,void *aParam3);
|
||||
|
||||
virtual void NotifyError(nsIImageRequest *aImageRequest,nsImageError aErrorType);
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
MyObserver::MyObserver()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
MyObserver::~MyObserver()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS(MyObserver, kIImageObserverIID)
|
||||
|
||||
void
|
||||
MyObserver::Notify(nsIImageRequest *aImageRequest,
|
||||
nsIImage *aImage,
|
||||
nsImageNotification aNotificationType,
|
||||
PRInt32 aParam1, PRInt32 aParam2,
|
||||
void *aParam3)
|
||||
{
|
||||
switch (aNotificationType)
|
||||
{
|
||||
case nsImageNotification_kDimensions:
|
||||
{
|
||||
char buffer[40];
|
||||
sprintf(buffer, "Image:%d x %d", aParam1, aParam2);
|
||||
::SetWindowText(gHwnd, buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsImageNotification_kPixmapUpdate:
|
||||
case nsImageNotification_kImageComplete:
|
||||
case nsImageNotification_kFrameComplete:
|
||||
{
|
||||
if (gImage == nsnull && aImage)
|
||||
{
|
||||
gImage = aImage;
|
||||
NS_ADDREF(aImage);
|
||||
}
|
||||
|
||||
if (!gInstalledColorMap && gImage)
|
||||
{
|
||||
nsColorMap *cmap = gImage->GetColorMap();
|
||||
|
||||
if (cmap != nsnull && cmap->NumColors > 0)
|
||||
{
|
||||
gWindow->SetColorMap(cmap);
|
||||
}
|
||||
gInstalledColorMap = PR_TRUE;
|
||||
}
|
||||
nsRect *rect = (nsRect *)aParam3;
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
|
||||
if (gImage)
|
||||
{
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void
|
||||
MyObserver::NotifyError(nsIImageRequest *aImageRequest,
|
||||
nsImageError aErrorType)
|
||||
{
|
||||
::MessageBox(NULL, "Image loading error!",class1Name, MB_OK);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// This tests the compositing for the image
|
||||
void
|
||||
Compositetest(PRInt32 aTestNum,nsIImage *aImage,nsIImage *aBImage,nsIImage *aMImage, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
nsPoint *location;
|
||||
PRUint32 min,seconds,milli,i,h,w;
|
||||
nsBlendQuality quality=nsMedQual;
|
||||
SYSTEMTIME thetime;
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
nsIImage *theimage;
|
||||
|
||||
|
||||
if(aTestNum == 1)
|
||||
{
|
||||
location = new nsPoint(aX,aY);
|
||||
if(aMImage)
|
||||
{
|
||||
aBImage->SetAlphaMask(aMImage);
|
||||
aBImage->MoveAlphaMask(rand() % aImage->GetWidth(),rand() % aImage->GetHeight());
|
||||
}
|
||||
|
||||
if(aMImage == nsnull)
|
||||
{
|
||||
location->x = rand() % aImage->GetWidth();
|
||||
location->y = rand() % aImage->GetHeight();
|
||||
printf("\n Image Location is %d, %d\n", location->x,location->y);
|
||||
}
|
||||
|
||||
aImage->CompositeImage(aBImage,location,quality);
|
||||
}
|
||||
|
||||
// speed test
|
||||
if(aTestNum == 2)
|
||||
{
|
||||
printf("\nSTARTING Blending TEST\n");
|
||||
::GetSystemTime(&thetime);
|
||||
min = thetime.wMinute;
|
||||
seconds = thetime.wSecond;
|
||||
milli = thetime.wMilliseconds;
|
||||
location = new nsPoint(aX,aY);
|
||||
w = gImage->GetWidth();
|
||||
h = gImage->GetHeight();
|
||||
|
||||
if(aMImage)
|
||||
{
|
||||
aBImage->SetAlphaMask(aMImage);
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
aBImage->MoveAlphaMask(rand()%w,rand()%h);
|
||||
theimage = aImage->DuplicateImage();
|
||||
theimage->CompositeImage(aBImage,location,quality);
|
||||
drawCtx->DrawImage(theimage, 0, 0, theimage->GetWidth(), theimage->GetHeight());
|
||||
NS_RELEASE(theimage);
|
||||
|
||||
// non buffered
|
||||
//aImage->CompositeImage(aBImage,location,quality);
|
||||
//drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
aBImage->MoveAlphaMask(rand()%w,rand()%h);
|
||||
//theimage = aImage->DuplicateImage();
|
||||
//theimage->CompositeImage(aBImage,location,quality);
|
||||
//drawCtx->DrawImage(theimage, 0, 0, theimage->GetWidth(), theimage->GetHeight());
|
||||
//NS_RELEASE(theimage);
|
||||
|
||||
// non buffered
|
||||
aImage->CompositeImage(aBImage,location,quality);
|
||||
drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
::GetSystemTime(&thetime);
|
||||
min = thetime.wMinute-min;
|
||||
if(min>0)
|
||||
min = min*60;
|
||||
seconds = min+thetime.wSecond-seconds;
|
||||
if(seconds>0)
|
||||
seconds = (seconds*1000)+thetime.wMilliseconds;
|
||||
else
|
||||
seconds = thetime.wMilliseconds;
|
||||
milli=seconds-milli;
|
||||
|
||||
printf("The composite Time was %lu Milliseconds\n",milli);
|
||||
}
|
||||
|
||||
|
||||
if(aTestNum == 3)
|
||||
{
|
||||
location = new nsPoint(aX,aY);
|
||||
|
||||
if(aMImage)
|
||||
{
|
||||
aBImage->SetAlphaMask(aMImage);
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
DWORD pos = ::GetMessagePos();
|
||||
POINT cpos;
|
||||
|
||||
cpos.x = LOWORD(pos);
|
||||
cpos.y = HIWORD(pos);
|
||||
|
||||
::ScreenToClient(gHwnd, &cpos);
|
||||
|
||||
aBImage->MoveAlphaMask(cpos.x,cpos.y);
|
||||
|
||||
theimage = aImage->DuplicateImage();
|
||||
theimage->CompositeImage(aBImage,location,quality);
|
||||
drawCtx->DrawImage(theimage, 0, 0, theimage->GetWidth(), theimage->GetHeight());
|
||||
NS_RELEASE(theimage);
|
||||
|
||||
MSG msg;
|
||||
if (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
aBImage->MoveAlphaMask(rand()%w,rand()%h);
|
||||
theimage = aImage->DuplicateImage();
|
||||
theimage->CompositeImage(aBImage,location,quality);
|
||||
drawCtx->DrawImage(theimage, 0, 0, theimage->GetWidth(), theimage->GetHeight());
|
||||
NS_RELEASE(theimage);
|
||||
}
|
||||
}
|
||||
|
||||
drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight());
|
||||
|
||||
// we are finished with this
|
||||
if (gBlendImage)
|
||||
{
|
||||
NS_RELEASE(gBlendImage);
|
||||
gBlendImage = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// This tests the speed for the bliting,
|
||||
PRInt32
|
||||
speedtest(nsIImage *aTheImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,PRBool aOptimize)
|
||||
{
|
||||
PRUint32 min,seconds,milli,i;
|
||||
SYSTEMTIME thetime;
|
||||
|
||||
printf("\nSTARTING TIMING TEST\n");
|
||||
::GetSystemTime(&thetime);
|
||||
min = thetime.wMinute;
|
||||
seconds = thetime.wSecond;
|
||||
milli = thetime.wMilliseconds;
|
||||
|
||||
if(aOptimize==PR_TRUE)
|
||||
aTheImage->Optimize(aSurface);
|
||||
|
||||
for(i=0;i<200;i++)
|
||||
aSurface->DrawImage(aTheImage,aX,aY,aWidth,aHeight);
|
||||
|
||||
::GetSystemTime(&thetime);
|
||||
min = thetime.wMinute-min;
|
||||
if(min>0)
|
||||
min = min*60;
|
||||
seconds = min+thetime.wSecond-seconds;
|
||||
if(seconds>0)
|
||||
seconds = (seconds*1000)+thetime.wMilliseconds;
|
||||
else
|
||||
seconds = thetime.wMilliseconds;
|
||||
milli=seconds-milli;
|
||||
|
||||
if(aOptimize==PR_TRUE)
|
||||
printf("The Optimized Blitting Time was %lu Milliseconds\n",milli);
|
||||
else
|
||||
printf("The Non-Optimized Blitting Time was %lu Milliseconds\n",milli);
|
||||
|
||||
return(milli);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRInt32
|
||||
arctest(nsIRenderingContext *aSurface)
|
||||
{
|
||||
nsFont *font;
|
||||
nscolor white,black;
|
||||
|
||||
font = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,NS_FONT_WEIGHT_BOLD,0,12);
|
||||
aSurface->SetFont(*font);
|
||||
|
||||
// clear surface
|
||||
NS_ColorNameToRGB("white", &white);
|
||||
NS_ColorNameToRGB("red", &black);
|
||||
aSurface->SetColor(white);
|
||||
aSurface->FillRect(0,0,1000,1000);
|
||||
aSurface->SetColor(black);
|
||||
|
||||
aSurface->DrawArc(20, 20,50,100,(float)0.0,(float)90.0);
|
||||
aSurface->FillArc(70, 20,50,100,(float)0.0,(float)90.0);
|
||||
aSurface->DrawArc(150, 20,50,100,(float)90.0,(float)0.0);
|
||||
aSurface->DrawString("0 to 90\0",20,8,30);
|
||||
aSurface->DrawString("Reverse (eg 90 to 0)\0",120,8,30);
|
||||
|
||||
aSurface->DrawArc(20, 140,100,50,(float)130.0,(float)180.0);
|
||||
aSurface->FillArc(70, 140,100,50,(float)130.0,(float)180.0);
|
||||
aSurface->DrawArc(150, 140,100,50,(float)180.0,(float)130.0);
|
||||
aSurface->DrawString("130 to 180\0",20,130,30);
|
||||
|
||||
aSurface->DrawArc(20, 200,50,100,(float)170.0,(float)300.0);
|
||||
aSurface->FillArc(70, 200,50,100,(float)170.0,(float)300.0);
|
||||
aSurface->DrawArc(150, 200,50,100,(float)300.0,(float)170.0);
|
||||
aSurface->DrawString("170 to 300\0",20,190,30);
|
||||
|
||||
|
||||
return(30);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRInt32
|
||||
drawtest(nsIRenderingContext *aSurface)
|
||||
{
|
||||
nsFont *font;
|
||||
nsPoint *pointlist;
|
||||
nscolor white,black;
|
||||
|
||||
font = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,NS_FONT_WEIGHT_BOLD,0,12);
|
||||
aSurface->SetFont(*font);
|
||||
|
||||
|
||||
// clear surface
|
||||
NS_ColorNameToRGB("white", &white);
|
||||
NS_ColorNameToRGB("black", &black);
|
||||
aSurface->SetColor(white);
|
||||
aSurface->FillRect(0,0,1000,1000);
|
||||
aSurface->SetColor(black);
|
||||
|
||||
aSurface->DrawRect(20, 20, 100, 100);
|
||||
aSurface->DrawString("This is a Rectangle\0",20,5,30);
|
||||
|
||||
aSurface->DrawLine(0,0,300,400);
|
||||
|
||||
pointlist = new nsPoint[6];
|
||||
pointlist[0].x = 150;pointlist[0].y = 150;
|
||||
pointlist[1].x = 200;pointlist[1].y = 150;
|
||||
pointlist[2].x = 190;pointlist[2].y = 170;
|
||||
pointlist[3].x = 210;pointlist[3].y = 190;
|
||||
pointlist[4].x = 175;pointlist[4].y = 175;
|
||||
pointlist[5].x = 150;pointlist[5].y = 150;
|
||||
aSurface->DrawPolygon(pointlist,6);
|
||||
aSurface->DrawString("This is a closed Polygon\0",210,150,30);
|
||||
delete [] pointlist;
|
||||
|
||||
#ifdef WINDOWSBROKEN
|
||||
pointlist = new nsPoint[5];
|
||||
pointlist[0].x = 200;pointlist[0].y = 200;
|
||||
pointlist[1].x = 250;pointlist[1].y = 200;
|
||||
pointlist[2].x = 240;pointlist[2].y = 220;
|
||||
pointlist[3].x = 260;pointlist[3].y = 240;
|
||||
pointlist[4].x = 225;pointlist[4].y = 225;
|
||||
aSurface->DrawPolygon(pointlist,6);
|
||||
aSurface->DrawString("This is an open Polygon\0",250,200,30);
|
||||
delete [] pointlist;
|
||||
#endif
|
||||
|
||||
aSurface->DrawEllipse(30, 150,50,100);
|
||||
aSurface->DrawString("This is an Ellipse\0",30,140,30);
|
||||
|
||||
|
||||
return(30);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRInt32
|
||||
filltest(nsIRenderingContext *aSurface)
|
||||
{
|
||||
nsFont *font;
|
||||
nsPoint *pointlist;
|
||||
nscolor white,black;
|
||||
|
||||
font = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,NS_FONT_WEIGHT_BOLD,0,12);
|
||||
aSurface->SetFont(*font);
|
||||
|
||||
// clear surface
|
||||
NS_ColorNameToRGB("white", &white);
|
||||
NS_ColorNameToRGB("black", &black);
|
||||
aSurface->SetColor(white);
|
||||
aSurface->FillRect(0,0,1000,1000);
|
||||
aSurface->SetColor(black);
|
||||
|
||||
aSurface->FillRect(20, 20, 100, 100);
|
||||
aSurface->DrawString("This is a Rectangle\0",20,5,30);
|
||||
|
||||
pointlist = new nsPoint[6];
|
||||
pointlist[0].x = 150;pointlist[0].y = 150;
|
||||
pointlist[1].x = 200;pointlist[1].y = 150;
|
||||
pointlist[2].x = 190;pointlist[2].y = 170;
|
||||
pointlist[3].x = 210;pointlist[3].y = 190;
|
||||
pointlist[4].x = 175;pointlist[4].y = 175;
|
||||
pointlist[5].x = 150;pointlist[5].y = 150;
|
||||
aSurface->FillPolygon(pointlist,6);
|
||||
aSurface->DrawString("This is a closed Polygon\0",210,150,30);
|
||||
delete [] pointlist;
|
||||
|
||||
|
||||
#ifdef WINDOWSBROKEN
|
||||
pointlist = new nsPoint[5];
|
||||
pointlist[0].x = 200;pointlist[0].y = 200;
|
||||
pointlist[1].x = 250;pointlist[1].y = 200;
|
||||
pointlist[2].x = 240;pointlist[2].y = 220;
|
||||
pointlist[3].x = 260;pointlist[3].y = 240;
|
||||
pointlist[4].x = 225;pointlist[4].y = 225;
|
||||
aSurface->FillPolygon(pointlist,6);
|
||||
aSurface->DrawString("This is an open Polygon\0",250,200,30);
|
||||
delete [] pointlist;
|
||||
#endif
|
||||
|
||||
aSurface->FillEllipse(30, 150,50,100);
|
||||
aSurface->DrawString("This is an Ellipse\0",30,140,30);
|
||||
|
||||
return(30);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
nsEventStatus PR_CALLBACK
|
||||
MyHandleEvent(nsGUIEvent *aEvent)
|
||||
{
|
||||
nsEventStatus result = nsEventStatus_eConsumeNoDefault;
|
||||
switch(aEvent->message)
|
||||
{
|
||||
case NS_PAINT:
|
||||
{
|
||||
// paint the background
|
||||
nsIRenderingContext *drawCtx = ((nsPaintEvent*)aEvent)->renderingContext;
|
||||
drawCtx->SetColor(aEvent->widget->GetBackgroundColor());
|
||||
drawCtx->FillRect(*(((nsPaintEvent*)aEvent)->rect));
|
||||
if (gImage)
|
||||
{
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
}
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void
|
||||
MyReleaseImages()
|
||||
{
|
||||
if (gImageReq)
|
||||
{
|
||||
NS_RELEASE(gImageReq);
|
||||
gImageReq = NULL;
|
||||
}
|
||||
if (gImage)
|
||||
{
|
||||
NS_RELEASE(gImage);
|
||||
gImage = NULL;
|
||||
}
|
||||
|
||||
gInstalledColorMap = PR_FALSE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void
|
||||
MyInterrupt()
|
||||
{
|
||||
if (gImageGroup)
|
||||
{
|
||||
gImageGroup->Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
#define FILE_URL_PREFIX "file://"
|
||||
|
||||
void
|
||||
MyLoadImage(char *aFileName,PRBool aGenLoad,nsIImage **aTheImage)
|
||||
{
|
||||
char fileURL[256];
|
||||
char *str;
|
||||
|
||||
MyInterrupt();
|
||||
if(aGenLoad!=PR_TRUE)
|
||||
MyReleaseImages();
|
||||
|
||||
if (gImageGroup == NULL)
|
||||
{
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
if (NS_NewImageGroup(&gImageGroup) != NS_OK || gImageGroup->Init(drawCtx) != NS_OK)
|
||||
{
|
||||
::MessageBox(NULL, "Couldn't create image group",class1Name, MB_OK);
|
||||
NS_RELEASE(drawCtx);
|
||||
return;
|
||||
}
|
||||
NS_RELEASE(drawCtx);
|
||||
}
|
||||
|
||||
strcpy(fileURL, FILE_URL_PREFIX);
|
||||
strcpy(fileURL + strlen(FILE_URL_PREFIX), aFileName);
|
||||
|
||||
str = fileURL;
|
||||
while ((str = strchr(str, '\\')) != NULL)
|
||||
*str = '/';
|
||||
|
||||
nscolor white;
|
||||
|
||||
// set up which image gets loaded
|
||||
if(aGenLoad == PR_TRUE)
|
||||
{
|
||||
MyBlendObserver *observer = new MyBlendObserver(aTheImage);
|
||||
NS_ColorNameToRGB("white", &white);
|
||||
gImageReq = gImageGroup->GetImage(fileURL,observer,white, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
MyObserver *observer = new MyObserver();
|
||||
NS_ColorNameToRGB("white", &white);
|
||||
gImageReq = gImageGroup->GetImage(fileURL,observer,white, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (gImageReq == NULL)
|
||||
{
|
||||
::MessageBox(NULL, "Couldn't create image request",class1Name, MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRBool
|
||||
OpenFileDialog(char *aBuffer, int32 aBufLen)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
OPENFILENAME ofn;
|
||||
|
||||
// *.js is the standard File Name on the Save/Open Dialog
|
||||
::strcpy(aBuffer, "*.gif;*.png;*.jpg;*.jpeg");
|
||||
|
||||
// fill the OPENFILENAME sruct
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = gHwnd;
|
||||
ofn.hInstance = gInstance;
|
||||
ofn.lpstrFilter = "All Images (*.gif,*.png,*.jpg,*.jpeg)\0*.gif;*png;*.jpg;*.jpeg\0GIF Files (*.gif)\0*.gif\0PNG Files (*.png)\0*.png\0JPEG Files (*.jpg,*.jpeg)\0*.jpg;*.jpeg\0All Files\0*.*\0\0";
|
||||
ofn.lpstrCustomFilter = NULL;
|
||||
ofn.nMaxCustFilter = 0;
|
||||
ofn.nFilterIndex = 1; // the first one in lpstrFilter
|
||||
ofn.lpstrFile = aBuffer; // contains the file path name on return
|
||||
ofn.nMaxFile = aBufLen;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL; // use default
|
||||
ofn.lpstrTitle = NULL; // use default
|
||||
ofn.Flags = OFN_CREATEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
|
||||
ofn.nFileOffset = 0;
|
||||
ofn.nFileExtension = 0;
|
||||
ofn.lpstrDefExt = "gif"; // default extension is .js
|
||||
ofn.lCustData = NULL;
|
||||
ofn.lpfnHook = NULL;
|
||||
ofn.lpTemplateName = NULL;
|
||||
|
||||
// call the open file dialog or the save file dialog according to aIsOpenDialog
|
||||
result = ::GetOpenFileName(&ofn);
|
||||
|
||||
return (PRBool)result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRBool
|
||||
IsImageLoaded()
|
||||
{
|
||||
|
||||
if(gImageGroup == NULL) // go get an image for the window
|
||||
{
|
||||
char szFile[256];
|
||||
|
||||
::MessageBox(NULL, "Need To Open an Image",NULL, MB_OK);
|
||||
|
||||
if (!OpenFileDialog(szFile, 256))
|
||||
return PR_FALSE;
|
||||
MyLoadImage(szFile,PR_FALSE,NULL);
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
long PASCAL
|
||||
WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
|
||||
{
|
||||
HMENU hMenu;
|
||||
char szFile[256];
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
hMenu = GetMenu(hWnd);
|
||||
|
||||
switch (LOWORD(param))
|
||||
{
|
||||
case TIMER_OPEN:
|
||||
{
|
||||
|
||||
if (!OpenFileDialog(szFile, 256))
|
||||
return 0L;
|
||||
MyLoadImage(szFile,PR_FALSE,NULL);
|
||||
break;
|
||||
}
|
||||
case TIMER_EXIT:
|
||||
::DestroyWindow(hWnd);
|
||||
exit(0);
|
||||
break;
|
||||
case RDMSK:
|
||||
if (gMaskImage!=nsnull)
|
||||
{
|
||||
NS_RELEASE(gMaskImage);
|
||||
gMaskImage = nsnull;
|
||||
}
|
||||
if (OpenFileDialog(szFile, 256))
|
||||
MyLoadImage(szFile,PR_TRUE,&gMaskImage);
|
||||
break;
|
||||
case COMPINT:
|
||||
gTestNum = 3;
|
||||
case COMPTST:
|
||||
if(LOWORD(param) == COMPTST)
|
||||
gTestNum = 1;
|
||||
case COMPTSTSPEED:
|
||||
if(LOWORD(param) == COMPTSTSPEED)
|
||||
gTestNum = 2;
|
||||
IsImageLoaded();
|
||||
if(gImage)
|
||||
{
|
||||
if (gBlendImage!=nsnull)
|
||||
{
|
||||
NS_RELEASE(gBlendImage);
|
||||
gBlendImage = nsnull;
|
||||
}
|
||||
|
||||
gXOff = 100;
|
||||
gYOff = 100;
|
||||
if (OpenFileDialog(szFile, 256))
|
||||
MyLoadImage(szFile,PR_TRUE,&gBlendImage);
|
||||
}
|
||||
break;
|
||||
case BSTNOOPT:
|
||||
case BSTOPT:
|
||||
IsImageLoaded();
|
||||
if(gImage)
|
||||
{
|
||||
PRBool opt;
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
|
||||
if(LOWORD(param) == BSTNOOPT)
|
||||
opt = PR_FALSE;
|
||||
else
|
||||
opt = PR_TRUE;
|
||||
speedtest(gImage,drawCtx, 0, 0, gImage->GetWidth(), gImage->GetHeight(),opt);
|
||||
}
|
||||
break;
|
||||
case DRAWTEST:
|
||||
if(gWindow)
|
||||
{
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
drawtest(drawCtx);
|
||||
}
|
||||
break;
|
||||
case FILLTEST:
|
||||
if(gWindow)
|
||||
{
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
filltest(drawCtx);
|
||||
}
|
||||
break;
|
||||
case ARCTEST:
|
||||
if(gWindow)
|
||||
{
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
arctest(drawCtx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CREATE:
|
||||
// Initialize image library
|
||||
if (NS_NewImageManager(&gImageManager) != NS_OK||gImageManager->Init() != NS_OK)
|
||||
{
|
||||
::MessageBox(NULL, "Can't initialize the image library",class1Name, MB_OK);
|
||||
}
|
||||
gImageManager->SetCacheSize(1024*1024);
|
||||
break;
|
||||
|
||||
/*case WM_MOUSEMOVE:
|
||||
{
|
||||
DWORD pos = ::GetMessagePos();
|
||||
POINT cpos;
|
||||
|
||||
cpos.x = LOWORD(pos);
|
||||
cpos.y = HIWORD(pos);
|
||||
|
||||
::ScreenToClient(hWnd, &cpos);
|
||||
// Dothing(cpos.x, cpos.y);
|
||||
|
||||
}
|
||||
break;*/
|
||||
|
||||
case WM_DESTROY:
|
||||
MyInterrupt();
|
||||
MyReleaseImages();
|
||||
if (gImageGroup != nsnull)
|
||||
{
|
||||
NS_RELEASE(gImageGroup);
|
||||
}
|
||||
if (gImageManager != nsnull)
|
||||
{
|
||||
NS_RELEASE(gImageManager);
|
||||
}
|
||||
if (gBlendImage)
|
||||
{
|
||||
NS_RELEASE(gBlendImage);
|
||||
gBlendImage = NULL;
|
||||
}
|
||||
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, param, lparam);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
static HWND CreateTopLevel(const char* clazz, const char* title,int aWidth, int aHeight)
|
||||
{
|
||||
// Create a simple top level window
|
||||
HWND window = ::CreateWindowEx(WS_EX_CLIENTEDGE,
|
||||
clazz, title,
|
||||
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
aWidth, aHeight,
|
||||
HWND_DESKTOP,
|
||||
NULL,
|
||||
gInstance,
|
||||
NULL);
|
||||
|
||||
nsRect rect(0, 0, aWidth, aHeight);
|
||||
|
||||
nsresult rv = NSRepository::CreateInstance(kCChildWindowIID, NULL, kIWidgetIID, (void**)&gWindow);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
gWindow->Create((nsNativeWindow)window, rect, MyHandleEvent, NULL);
|
||||
}
|
||||
|
||||
::ShowWindow(window, SW_SHOW);
|
||||
::UpdateWindow(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
#define WIDGET_DLL "raptorwidget.dll"
|
||||
#define GFXWIN_DLL "raptorgfxwin.dll"
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
int PASCAL
|
||||
WinMain(HANDLE instance, HANDLE prevInstance, LPSTR cmdParam, int nCmdShow)
|
||||
{
|
||||
gInstance = instance;
|
||||
|
||||
NSRepository::RegisterFactory(kCWindowIID, WIDGET_DLL, PR_FALSE, PR_FALSE);
|
||||
NSRepository::RegisterFactory(kCChildWindowIID, WIDGET_DLL, PR_FALSE, PR_FALSE);
|
||||
NSRepository::RegisterFactory(kCScrollbarIID, WIDGET_DLL, PR_FALSE, PR_FALSE);
|
||||
|
||||
static NS_DEFINE_IID(kCRenderingContextIID, NS_RENDERING_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kCDeviceContextIID, NS_DEVICE_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kCFontMetricsIID, NS_FONT_METRICS_CID);
|
||||
static NS_DEFINE_IID(kCImageIID, NS_IMAGE_CID);
|
||||
|
||||
NSRepository::RegisterFactory(kCRenderingContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
|
||||
NSRepository::RegisterFactory(kCDeviceContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
|
||||
NSRepository::RegisterFactory(kCFontMetricsIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
|
||||
NSRepository::RegisterFactory(kCImageIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
|
||||
|
||||
if (!prevInstance) {
|
||||
WNDCLASS wndClass;
|
||||
wndClass.style = 0;
|
||||
wndClass.lpfnWndProc = WndProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = 0;
|
||||
wndClass.hInstance = gInstance;
|
||||
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wndClass.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
|
||||
wndClass.lpszMenuName = class1Name;
|
||||
wndClass.lpszClassName = class1Name;
|
||||
RegisterClass(&wndClass);
|
||||
}
|
||||
|
||||
// Create our first top level window
|
||||
gHwnd = CreateTopLevel(class1Name, "Graphics tester", 620, 400);
|
||||
|
||||
// Process messages
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
WinMain(GetModuleHandle(NULL), NULL, 0, SW_SHOW);
|
||||
}
|
||||
42
mozilla/gfx/tests/btest/image.rc
Normal file
42
mozilla/gfx/tests/btest/image.rc
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "resources.h"
|
||||
|
||||
IMAGETEST MENU DISCARDABLE
|
||||
{
|
||||
POPUP "File"
|
||||
{
|
||||
MENUITEM "Open...", TIMER_OPEN
|
||||
MENUITEM "Exit", TIMER_EXIT
|
||||
}
|
||||
|
||||
|
||||
POPUP "TEST"
|
||||
{
|
||||
MENUITEM "Read Mask", RDMSK
|
||||
MENUITEM "Composit Interactive",COMPINT
|
||||
MENUITEM "Composit Test", COMPTST
|
||||
MENUITEM "Composite Speed", COMPTSTSPEED
|
||||
MENUITEM "Blit Speed",BSTNOOPT
|
||||
MENUITEM "Blit Speed, Optimzed.",BSTOPT
|
||||
MENUITEM "Draw Test",DRAWTEST
|
||||
MENUITEM "Fill Test",FILLTEST
|
||||
MENUITEM "Arc Test",ARCTEST
|
||||
}
|
||||
|
||||
}
|
||||
62
mozilla/gfx/tests/btest/makefile.win
Normal file
62
mozilla/gfx/tests/btest/makefile.win
Normal file
@@ -0,0 +1,62 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
MAKE_OBJ_TYPE = EXE
|
||||
PROG0 = .\$(OBJDIR)\BitTest.exe
|
||||
RESFILE = image.res
|
||||
PROGRAMS = $(PROG0)
|
||||
|
||||
LINCS=-I$(XPDIST)\public\raptor -I$(XPDIST)\public\xpcom -I..\src
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\raptorbase.lib \
|
||||
$(DIST)\lib\raptorgfx.lib \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\libplc21.lib \
|
||||
$(DIST)\lib\img3240.lib \
|
||||
$(DIST)\lib\util.lib \
|
||||
comdlg32.lib \
|
||||
$(RESFILE)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(PROGRAMS)
|
||||
$(MAKE_INSTALL) $(PROG0) $(DIST)\bin
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\BitTest.exe
|
||||
|
||||
# Move this into config/obj.inc when it's allowed
|
||||
.cpp{.\$(OBJDIR)\}.exe:
|
||||
$(CC) @<<$(CFGFILE)
|
||||
$(CFLAGS)
|
||||
$(LCFLAGS)
|
||||
$(LINCS)
|
||||
$(LINCS_1)
|
||||
$(INCS)
|
||||
$(LLIBS)
|
||||
$(OS_LIBS)
|
||||
-Fd$(PBDFILE)
|
||||
-Fe.\$(OBJDIR)\
|
||||
-Fo.\$(OBJDIR)\
|
||||
$(CURDIR)$(*B).cpp
|
||||
<<
|
||||
|
||||
$(PROG0): $(OBJDIR) BitTest.cpp $(RESFILE)
|
||||
31
mozilla/gfx/tests/btest/resource.h
Normal file
31
mozilla/gfx/tests/btest/resource.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#define ID_MENUITEM40001 40001
|
||||
#define ID_MENUITEM40002 40002
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40003
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
35
mozilla/gfx/tests/btest/resources.h
Normal file
35
mozilla/gfx/tests/btest/resources.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef resources_h___
|
||||
#define resources_h___
|
||||
|
||||
#define TIMER_OPEN 40010
|
||||
#define TIMER_EXIT 40011
|
||||
|
||||
#define BSTNOOPT 40012
|
||||
#define BSTOPT 40013
|
||||
#define DRAWTEST 40014
|
||||
#define FILLTEST 40015
|
||||
#define ARCTEST 40016
|
||||
#define COMPTST 40017
|
||||
#define COMPTSTSPEED 40018
|
||||
#define RDMSK 40019
|
||||
#define COMPINT 40020
|
||||
|
||||
#endif /* resources_h___ */
|
||||
70
mozilla/gfx/tests/makefile.win
Normal file
70
mozilla/gfx/tests/makefile.win
Normal file
@@ -0,0 +1,70 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DIRS = btest
|
||||
|
||||
MAKE_OBJ_TYPE = EXE
|
||||
PROG1 = .\$(OBJDIR)\TestRect.exe
|
||||
PROG2 = .\$(OBJDIR)\TestColorNames.exe
|
||||
PROG3 = .\$(OBJDIR)\DumpColors.exe
|
||||
PROGRAMS = $(PROG1) $(PROG2) $(PROG3)
|
||||
|
||||
LINCS=-I$(XPDIST)\public\raptor -I$(XPDIST)\public\xpcom -I..\src
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\raptorbase.lib \
|
||||
$(DIST)\lib\raptorgfx.lib \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\libplc21.lib
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(PROGRAMS)
|
||||
$(MAKE_INSTALL) $(PROG1) $(DIST)\bin
|
||||
$(MAKE_INSTALL) $(PROG2) $(DIST)\bin
|
||||
$(MAKE_INSTALL) $(PROG3) $(DIST)\bin
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\TestRect.exe
|
||||
rm -f $(DIST)\bin\TestColorNames.exe
|
||||
rm -f $(DIST)\bin\DumpColors.exe
|
||||
|
||||
# Move this into config/obj.inc when it's allowed
|
||||
.cpp{.\$(OBJDIR)\}.exe:
|
||||
$(CC) @<<$(CFGFILE)
|
||||
$(CFLAGS)
|
||||
$(LCFLAGS)
|
||||
$(LINCS)
|
||||
$(LINCS_1)
|
||||
$(INCS)
|
||||
$(LLIBS)
|
||||
$(OS_LIBS)
|
||||
-Fd$(PBDFILE)
|
||||
-Fe.\$(OBJDIR)\
|
||||
-Fo.\$(OBJDIR)\
|
||||
$(CURDIR)$(*B).cpp
|
||||
<<
|
||||
|
||||
$(PROG1): $(OBJDIR) TestRect.cpp
|
||||
|
||||
$(PROG2): $(OBJDIR) TestColorNames.cpp
|
||||
|
||||
$(PROG3): $(OBJDIR) DumpColors.cpp
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 B |
@@ -1,97 +0,0 @@
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
|
||||
############################################################################
|
||||
# Module Initialization
|
||||
############################################################################
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
package Attachment;
|
||||
|
||||
# This module requires that its caller have said "require CGI.pl" to import
|
||||
# relevant functions from that script and its companion globals.pl.
|
||||
|
||||
############################################################################
|
||||
# Functions
|
||||
############################################################################
|
||||
|
||||
sub query
|
||||
{
|
||||
# Retrieves and returns an array of attachment records for a given bug.
|
||||
# This data should be given to attachment/list.atml in an
|
||||
# "attachments" variable.
|
||||
my ($bugid) = @_;
|
||||
|
||||
my $in_editbugs = &::UserInGroup("editbugs");
|
||||
|
||||
# Retrieve a list of attachments for this bug and write them into an array
|
||||
# of hashes in which each hash represents a single attachment.
|
||||
&::SendSQL("
|
||||
SELECT attach_id, creation_ts, mimetype, description, ispatch,
|
||||
isobsolete, submitter_id
|
||||
FROM attachments WHERE bug_id = $bugid ORDER BY attach_id
|
||||
");
|
||||
my @attachments = ();
|
||||
while (&::MoreSQLData()) {
|
||||
my %a;
|
||||
my $submitter_id;
|
||||
($a{'attachid'}, $a{'date'}, $a{'contenttype'}, $a{'description'},
|
||||
$a{'ispatch'}, $a{'isobsolete'}, $submitter_id) = &::FetchSQLData();
|
||||
|
||||
# Format the attachment's creation/modification date into a standard
|
||||
# format (YYYY-MM-DD HH:MM)
|
||||
if ($a{'date'} =~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
|
||||
$a{'date'} = "$1-$2-$3 $4:$5";
|
||||
}
|
||||
|
||||
# Retrieve a list of status flags that have been set on the attachment.
|
||||
&::PushGlobalSQLState();
|
||||
&::SendSQL("
|
||||
SELECT name
|
||||
FROM attachstatuses, attachstatusdefs
|
||||
WHERE attach_id = $a{'attachid'}
|
||||
AND attachstatuses.statusid = attachstatusdefs.id
|
||||
ORDER BY sortkey
|
||||
");
|
||||
my @statuses = ();
|
||||
while (&::MoreSQLData()) {
|
||||
my ($status) = &::FetchSQLData();
|
||||
push @statuses , $status;
|
||||
}
|
||||
$a{'statuses'} = \@statuses;
|
||||
&::PopGlobalSQLState();
|
||||
|
||||
# We will display the edit link if the user can edit the attachment;
|
||||
# ie the are the submitter, or they have canedit.
|
||||
# Also show the link if the user is not logged in - in that cae,
|
||||
# They'll be prompted later
|
||||
$a{'canedit'} = ($::userid == 0 || $submitter_id == $::userid ||
|
||||
$in_editbugs);
|
||||
push @attachments, \%a;
|
||||
}
|
||||
|
||||
return \@attachments;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,547 +0,0 @@
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Dawn Endico <endico@mozilla.org>
|
||||
# Terry Weissman <terry@mozilla.org>
|
||||
# Chris Yeh <cyeh@bluemartini.com>
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
use DBI;
|
||||
use RelationSet;
|
||||
use vars qw($unconfirmedstate $legal_keywords);
|
||||
require "globals.pl";
|
||||
require "CGI.pl";
|
||||
package Bug;
|
||||
use CGI::Carp qw(fatalsToBrowser);
|
||||
my %ok_field;
|
||||
|
||||
for my $key (qw (bug_id product version rep_platform op_sys bug_status
|
||||
resolution priority bug_severity component assigned_to
|
||||
reporter bug_file_loc short_desc target_milestone
|
||||
qa_contact status_whiteboard creation_ts groupset
|
||||
delta_ts votes whoid usergroupset comment query error) ){
|
||||
$ok_field{$key}++;
|
||||
}
|
||||
|
||||
# create a new empty bug
|
||||
#
|
||||
sub new {
|
||||
my $type = shift();
|
||||
my %bug;
|
||||
|
||||
# create a ref to an empty hash and bless it
|
||||
#
|
||||
my $self = {%bug};
|
||||
bless $self, $type;
|
||||
|
||||
# construct from a hash containing a bug's info
|
||||
#
|
||||
if ($#_ == 1) {
|
||||
$self->initBug(@_);
|
||||
} else {
|
||||
confess("invalid number of arguments \($#_\)($_)");
|
||||
}
|
||||
|
||||
# bless as a Bug
|
||||
#
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# dump info about bug into hash unless user doesn't have permission
|
||||
# user_id 0 is used when person is not logged in.
|
||||
#
|
||||
sub initBug {
|
||||
my $self = shift();
|
||||
my ($bug_id, $user_id) = (@_);
|
||||
|
||||
my $old_bug_id = $bug_id;
|
||||
if ((! defined $bug_id) || (!$bug_id) || (!&::detaint_natural($bug_id))) {
|
||||
# no bug number given
|
||||
$self->{'bug_id'} = $old_bug_id;
|
||||
$self->{'error'} = "InvalidBugId";
|
||||
return $self;
|
||||
}
|
||||
|
||||
# default userid 0, or get DBID if you used an email address
|
||||
unless (defined $user_id) {
|
||||
$user_id = 0;
|
||||
}
|
||||
else {
|
||||
if ($user_id =~ /^\@/) {
|
||||
$user_id = &::DBname_to_id($user_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&::ConnectToDatabase();
|
||||
&::GetVersionTable();
|
||||
|
||||
# this verification should already have been done by caller
|
||||
# my $loginok = quietly_check_login();
|
||||
|
||||
|
||||
$self->{'whoid'} = $user_id;
|
||||
&::SendSQL("SELECT groupset FROM profiles WHERE userid=$self->{'whoid'}");
|
||||
my $usergroupset = &::FetchOneColumn();
|
||||
if (!$usergroupset) { $usergroupset = '0' }
|
||||
$self->{'usergroupset'} = $usergroupset;
|
||||
|
||||
# Check to see if we can see this bug
|
||||
if (!&::CanSeeBug($bug_id, $user_id, $usergroupset)) {
|
||||
# Permission denied to see bug
|
||||
$self->{'bug_id'} = $old_bug_id;
|
||||
$self->{'error'} = "PermissionDenied";
|
||||
return $self;
|
||||
}
|
||||
|
||||
my $query = "";
|
||||
if ($::driver eq 'mysql') {
|
||||
$query = "
|
||||
select
|
||||
bugs.bug_id, product, version, rep_platform, op_sys, bug_status,
|
||||
resolution, priority, bug_severity, component, assigned_to, reporter,
|
||||
bug_file_loc, short_desc, target_milestone, qa_contact,
|
||||
status_whiteboard, date_format(creation_ts,'%Y-%m-%d %H:%i'),
|
||||
groupset, delta_ts, sum(votes.count)
|
||||
from bugs left join votes using(bug_id)
|
||||
where bugs.bug_id = $bug_id
|
||||
group by bugs.bug_id";
|
||||
} elsif ($::driver eq 'Pg') {
|
||||
$query = "
|
||||
select
|
||||
bugs.bug_id, product, version, rep_platform, op_sys, bug_status,
|
||||
resolution, priority, bug_severity, component, assigned_to, reporter,
|
||||
bug_file_loc, short_desc, target_milestone, qa_contact,
|
||||
status_whiteboard, creation_ts,
|
||||
groupset, delta_ts, sum(votes.count)
|
||||
from bugs left join votes using(bug_id)
|
||||
where bugs.bug_id = $bug_id
|
||||
and (bugs.groupset & int8($usergroupset)) = bugs.groupset
|
||||
group by bugs.bug_id, product, version, rep_platform, op_sys, bug_status,
|
||||
resolution, priority, bug_severity, component, assigned_to, reporter,
|
||||
bug_file_loc, short_desc, target_milestone, qa_contact, status_whiteboard,
|
||||
creation_ts, groupset, delta_ts";
|
||||
}
|
||||
|
||||
&::SendSQL($query);
|
||||
my @row;
|
||||
|
||||
if (@row = &::FetchSQLData()) {
|
||||
my $count = 0;
|
||||
my %fields;
|
||||
foreach my $field ("bug_id", "product", "version", "rep_platform",
|
||||
"op_sys", "bug_status", "resolution", "priority",
|
||||
"bug_severity", "component", "assigned_to", "reporter",
|
||||
"bug_file_loc", "short_desc", "target_milestone",
|
||||
"qa_contact", "status_whiteboard", "creation_ts",
|
||||
"groupset", "delta_ts", "votes") {
|
||||
$fields{$field} = shift @row;
|
||||
if ($fields{$field}) {
|
||||
$self->{$field} = $fields{$field};
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
} else {
|
||||
&::SendSQL("select groupset from bugs where bug_id = $bug_id");
|
||||
if (@row = &::FetchSQLData()) {
|
||||
$self->{'bug_id'} = $bug_id;
|
||||
$self->{'error'} = "NotPermitted";
|
||||
return $self;
|
||||
} else {
|
||||
$self->{'bug_id'} = $bug_id;
|
||||
$self->{'error'} = "NotFound";
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
$self->{'assigned_to'} = &::DBID_to_name($self->{'assigned_to'});
|
||||
$self->{'reporter'} = &::DBID_to_name($self->{'reporter'});
|
||||
|
||||
my $ccSet = new RelationSet;
|
||||
$ccSet->mergeFromDB("select who from cc where bug_id=$bug_id");
|
||||
my @cc = $ccSet->toArrayOfStrings();
|
||||
if (@cc) {
|
||||
$self->{'cc'} = \@cc;
|
||||
}
|
||||
|
||||
if (&::Param("useqacontact") && (defined $self->{'qa_contact'}) ) {
|
||||
my $name = $self->{'qa_contact'} > 0 ? &::DBID_to_name($self->{'qa_contact'}) :"";
|
||||
if ($name) {
|
||||
$self->{'qa_contact'} = $name;
|
||||
}
|
||||
}
|
||||
|
||||
if (@::legal_keywords) {
|
||||
&::SendSQL("SELECT keyworddefs.name
|
||||
FROM keyworddefs, keywords
|
||||
WHERE keywords.bug_id = $bug_id
|
||||
AND keyworddefs.id = keywords.keywordid
|
||||
ORDER BY keyworddefs.name");
|
||||
my @list;
|
||||
while (&::MoreSQLData()) {
|
||||
push(@list, &::FetchOneColumn());
|
||||
}
|
||||
if (@list) {
|
||||
$self->{'keywords'} = join(', ', @list);
|
||||
}
|
||||
}
|
||||
|
||||
&::SendSQL("select attach_id, creation_ts, description
|
||||
from attachments
|
||||
where bug_id = $bug_id");
|
||||
my @attachments;
|
||||
while (&::MoreSQLData()) {
|
||||
my ($attachid, $date, $desc) = (&::FetchSQLData());
|
||||
if ($date =~ /^(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
|
||||
$date = "$3/$4/$2 $5:$6";
|
||||
my %attach;
|
||||
$attach{'attachid'} = $attachid;
|
||||
$attach{'date'} = $date;
|
||||
$attach{'desc'} = $desc;
|
||||
push @attachments, \%attach;
|
||||
}
|
||||
}
|
||||
if (@attachments) {
|
||||
$self->{'attachments'} = \@attachments;
|
||||
}
|
||||
|
||||
&::SendSQL("select bug_id, who, bug_when, thetext
|
||||
from longdescs
|
||||
where bug_id = $bug_id");
|
||||
my @longdescs;
|
||||
while (&::MoreSQLData()) {
|
||||
my ($bug_id, $who, $bug_when, $thetext) = (&::FetchSQLData());
|
||||
my %longdesc;
|
||||
$longdesc{'who'} = $who;
|
||||
$longdesc{'bug_when'} = $bug_when;
|
||||
$longdesc{'thetext'} = $thetext;
|
||||
push @longdescs, \%longdesc;
|
||||
}
|
||||
if (@longdescs) {
|
||||
$self->{'longdescs'} = \@longdescs;
|
||||
}
|
||||
|
||||
if (&::Param("usedependencies")) {
|
||||
my @depends = EmitDependList("blocked", "dependson", $bug_id);
|
||||
if ( @depends ) {
|
||||
$self->{'dependson'} = \@depends;
|
||||
}
|
||||
my @blocks = EmitDependList("dependson", "blocked", $bug_id);
|
||||
if ( @blocks ) {
|
||||
$self->{'blocks'} = \@blocks;
|
||||
}
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# given a bug hash, emit xml for it. with file header provided by caller
|
||||
#
|
||||
sub emitXML {
|
||||
( $#_ == 0 ) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
my $xml;
|
||||
|
||||
|
||||
if (exists $self->{'error'}) {
|
||||
$xml .= "<bug error=\"$self->{'error'}\">\n";
|
||||
$xml .= " <bug_id>$self->{'bug_id'}</bug_id>\n";
|
||||
$xml .= "</bug>\n";
|
||||
return $xml;
|
||||
}
|
||||
|
||||
$xml .= "<bug>\n";
|
||||
|
||||
foreach my $field ("bug_id", "bug_status", "product",
|
||||
"priority", "version", "rep_platform", "assigned_to", "delta_ts",
|
||||
"component", "reporter", "target_milestone", "bug_severity",
|
||||
"creation_ts", "qa_contact", "op_sys", "resolution", "bug_file_loc",
|
||||
"short_desc", "keywords", "status_whiteboard") {
|
||||
if ($self->{$field}) {
|
||||
$xml .= " <$field>" . QuoteXMLChars($self->{$field}) . "</$field>\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $field ("dependson", "blocks", "cc") {
|
||||
if (defined $self->{$field}) {
|
||||
for (my $i=0 ; $i < @{$self->{$field}} ; $i++) {
|
||||
$xml .= " <$field>" . $self->{$field}[$i] . "</$field>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $self->{'longdescs'}) {
|
||||
for (my $i=0 ; $i < @{$self->{'longdescs'}} ; $i++) {
|
||||
$xml .= " <long_desc>\n";
|
||||
$xml .= " <who>" . &::DBID_to_name($self->{'longdescs'}[$i]->{'who'})
|
||||
. "</who>\n";
|
||||
$xml .= " <bug_when>" . $self->{'longdescs'}[$i]->{'bug_when'}
|
||||
. "</bug_when>\n";
|
||||
$xml .= " <thetext>" . QuoteXMLChars($self->{'longdescs'}[$i]->{'thetext'})
|
||||
. "</thetext>\n";
|
||||
$xml .= " </long_desc>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $self->{'attachments'}) {
|
||||
for (my $i=0 ; $i < @{$self->{'attachments'}} ; $i++) {
|
||||
$xml .= " <attachment>\n";
|
||||
$xml .= " <attachid>" . $self->{'attachments'}[$i]->{'attachid'}
|
||||
. "</attachid>\n";
|
||||
$xml .= " <date>" . $self->{'attachments'}[$i]->{'date'} . "</date>\n";
|
||||
$xml .= " <desc>" . QuoteXMLChars($self->{'attachments'}[$i]->{'desc'}) . "</desc>\n";
|
||||
# $xml .= " <type>" . $self->{'attachments'}[$i]->{'type'} . "</type>\n";
|
||||
# $xml .= " <data>" . $self->{'attachments'}[$i]->{'data'} . "</data>\n";
|
||||
$xml .= " </attachment>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$xml .= "</bug>\n";
|
||||
return $xml;
|
||||
}
|
||||
|
||||
sub EmitDependList {
|
||||
my ($myfield, $targetfield, $bug_id) = (@_);
|
||||
my @list;
|
||||
&::SendSQL("select dependencies.$targetfield, bugs.bug_status
|
||||
from dependencies, bugs
|
||||
where dependencies.$myfield = $bug_id
|
||||
and bugs.bug_id = dependencies.$targetfield
|
||||
order by dependencies.$targetfield");
|
||||
while (&::MoreSQLData()) {
|
||||
my ($i, $stat) = (&::FetchSQLData());
|
||||
push @list, $i;
|
||||
}
|
||||
return @list;
|
||||
}
|
||||
|
||||
sub QuoteXMLChars {
|
||||
$_[0] =~ s/&/&/g;
|
||||
$_[0] =~ s/</</g;
|
||||
$_[0] =~ s/>/>/g;
|
||||
$_[0] =~ s/'/'/g;
|
||||
$_[0] =~ s/"/"/g;
|
||||
# $_[0] =~ s/([\x80-\xFF])/&XmlUtf8Encode(ord($1))/ge;
|
||||
return($_[0]);
|
||||
}
|
||||
|
||||
sub XML_Header {
|
||||
my ($urlbase, $version, $maintainer, $exporter) = (@_);
|
||||
|
||||
my $xml;
|
||||
$xml = "<?xml version=\"1.0\" standalone=\"yes\"?>\n";
|
||||
$xml .= "<!DOCTYPE bugzilla SYSTEM \"$urlbase";
|
||||
if (! ($urlbase =~ /.+\/$/)) {
|
||||
$xml .= "/";
|
||||
}
|
||||
$xml .= "bugzilla.dtd\">\n";
|
||||
$xml .= "<bugzilla";
|
||||
if (defined $exporter) {
|
||||
$xml .= " exporter=\"$exporter\"";
|
||||
}
|
||||
$xml .= " version=\"$version\"";
|
||||
$xml .= " urlbase=\"$urlbase\"";
|
||||
$xml .= " maintainer=\"$maintainer\">\n";
|
||||
return ($xml);
|
||||
}
|
||||
|
||||
|
||||
sub XML_Footer {
|
||||
return ("</bugzilla>\n");
|
||||
}
|
||||
|
||||
sub UserInGroup {
|
||||
my $self = shift();
|
||||
my ($groupname) = (@_);
|
||||
if ($self->{'usergroupset'} eq "0") {
|
||||
return 0;
|
||||
}
|
||||
&::ConnectToDatabase();
|
||||
&::SendSQL("select (group_bit & int8($self->{'usergroupset'})) != 0 from groups where name = "
|
||||
. &::SqlQuote($groupname));
|
||||
my $bit = &::FetchOneColumn();
|
||||
if ($bit) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub CanChangeField {
|
||||
my $self = shift();
|
||||
my ($f, $oldvalue, $newvalue) = (@_);
|
||||
my $UserInEditGroupSet = -1;
|
||||
my $UserInCanConfirmGroupSet = -1;
|
||||
my $ownerid;
|
||||
my $reporterid;
|
||||
my $qacontactid;
|
||||
|
||||
if ($f eq "assigned_to" || $f eq "reporter" || $f eq "qa_contact") {
|
||||
if ($oldvalue =~ /^\d+$/) {
|
||||
if ($oldvalue == 0) {
|
||||
$oldvalue = "";
|
||||
} else {
|
||||
$oldvalue = &::DBID_to_name($oldvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($oldvalue eq $newvalue) {
|
||||
return 1;
|
||||
}
|
||||
if (&::trim($oldvalue) eq &::trim($newvalue)) {
|
||||
return 1;
|
||||
}
|
||||
if ($f =~ /^longdesc/) {
|
||||
return 1;
|
||||
}
|
||||
if ($UserInEditGroupSet < 0) {
|
||||
$UserInEditGroupSet = UserInGroup($self, "editbugs");
|
||||
}
|
||||
if ($UserInEditGroupSet) {
|
||||
return 1;
|
||||
}
|
||||
&::SendSQL("SELECT reporter, assigned_to, qa_contact FROM bugs " .
|
||||
"WHERE bug_id = $self->{'bug_id'}");
|
||||
($reporterid, $ownerid, $qacontactid) = (&::FetchSQLData());
|
||||
|
||||
# Let reporter change bug status, even if they can't edit bugs.
|
||||
# If reporter can't re-open their bug they will just file a duplicate.
|
||||
# While we're at it, let them close their own bugs as well.
|
||||
if ( ($f eq "bug_status") && ($self->{'whoid'} eq $reporterid) ) {
|
||||
return 1;
|
||||
}
|
||||
if ($f eq "bug_status" && $newvalue ne $::unconfirmedstate &&
|
||||
&::IsOpenedState($newvalue)) {
|
||||
|
||||
# Hmm. They are trying to set this bug to some opened state
|
||||
# that isn't the UNCONFIRMED state. Are they in the right
|
||||
# group? Or, has it ever been confirmed? If not, then this
|
||||
# isn't legal.
|
||||
|
||||
if ($UserInCanConfirmGroupSet < 0) {
|
||||
$UserInCanConfirmGroupSet = &::UserInGroup("canconfirm");
|
||||
}
|
||||
if ($UserInCanConfirmGroupSet) {
|
||||
return 1;
|
||||
}
|
||||
&::SendSQL("SELECT everconfirmed FROM bugs WHERE bug_id = $self->{'bug_id'}");
|
||||
my $everconfirmed = FetchOneColumn();
|
||||
if ($everconfirmed) {
|
||||
return 1;
|
||||
}
|
||||
} elsif ($reporterid eq $self->{'whoid'} || $ownerid eq $self->{'whoid'} ||
|
||||
$qacontactid eq $self->{'whoid'}) {
|
||||
return 1;
|
||||
}
|
||||
$self->{'error'} = "
|
||||
Only the owner or submitter of the bug, or a sufficiently
|
||||
empowered user, may make that change to the $f field."
|
||||
}
|
||||
|
||||
sub Collision {
|
||||
my $self = shift();
|
||||
my $write = "WRITE"; # Might want to make a param to control
|
||||
# whether we do LOW_PRIORITY ...
|
||||
if ($::driver eq 'mysql') {
|
||||
&::SendSQL("LOCK TABLES bugs $write, bugs_activity $write, cc $write, " .
|
||||
"cc AS selectVisible_cc $write, " .
|
||||
"profiles $write, dependencies $write, votes $write, " .
|
||||
"keywords $write, longdescs $write, fielddefs $write, " .
|
||||
"keyworddefs READ, groups READ, attachments READ, products READ");
|
||||
}
|
||||
&::SendSQL("SELECT delta_ts FROM bugs where bug_id=$self->{'bug_id'}");
|
||||
my $delta_ts = &::FetchOneColumn();
|
||||
if ($::driver eq 'mysql') {
|
||||
&::SendSQL("unlock tables");
|
||||
}
|
||||
if ($self->{'delta_ts'} ne $delta_ts) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub AppendComment {
|
||||
my $self = shift();
|
||||
my ($comment) = (@_);
|
||||
$comment =~ s/\r\n/\n/g; # Get rid of windows-style line endings.
|
||||
$comment =~ s/\r/\n/g; # Get rid of mac-style line endings.
|
||||
if ($comment =~ /^\s*$/) { # Nothin' but whitespace.
|
||||
return;
|
||||
}
|
||||
|
||||
&::SendSQL("INSERT INTO longdescs (bug_id, who, bug_when, thetext) " .
|
||||
"VALUES($self->{'bug_id'}, $self->{'whoid'}, now(), " . &::SqlQuote($comment) . ")");
|
||||
|
||||
&::SendSQL("UPDATE bugs SET delta_ts = now() WHERE bug_id = $self->{'bug_id'}");
|
||||
}
|
||||
|
||||
|
||||
#from o'reilley's Programming Perl
|
||||
sub display {
|
||||
my $self = shift;
|
||||
my @keys;
|
||||
if (@_ == 0) { # no further arguments
|
||||
@keys = sort keys(%$self);
|
||||
} else {
|
||||
@keys = @_; # use the ones given
|
||||
}
|
||||
foreach my $key (@keys) {
|
||||
print "\t$key => $self->{$key}\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub CommitChanges {
|
||||
|
||||
#snapshot bug
|
||||
#snapshot dependencies
|
||||
#check can change fields
|
||||
#check collision
|
||||
#lock and change fields
|
||||
#notify through mail
|
||||
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
use vars qw($AUTOLOAD);
|
||||
my $self = shift;
|
||||
my $type = ref($self) || $self;
|
||||
my $attr = $AUTOLOAD;
|
||||
|
||||
$attr =~ s/.*:://;
|
||||
return unless $attr=~ /[^A-Z]/;
|
||||
if (@_) {
|
||||
$self->{$attr} = shift;
|
||||
return;
|
||||
}
|
||||
confess ("invalid bug attribute $attr") unless $ok_field{$attr};
|
||||
if (defined $self->{$attr}) {
|
||||
return $self->{$attr};
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
* This README is no longer used to house installation instructions. Instead,
|
||||
it contains pointers to where you may find the information you need.
|
||||
|
||||
* Installation instructions are now found in docs/, with a variety of document
|
||||
types available. Please refer to these documents when installing, configuring,
|
||||
and maintaining your Bugzilla installation. A helpful starting point is
|
||||
docs/txt/Bugzilla-Guide.txt, or with a web browser at docs/html/index.html.
|
||||
|
||||
* Release notes for people upgrading to a new version of Bugzilla are
|
||||
available at docs/rel_notes.txt.
|
||||
|
||||
* If you wish to contribute to the documentation, please read docs/README.docs.
|
||||
|
||||
* The Bugzilla web site is at "http://www.mozilla.org/projects/bugzilla/".
|
||||
This site will contain the latest Bugzilla information, including how to
|
||||
report bugs and how to get help with Bugzilla.
|
||||
@@ -1,268 +0,0 @@
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Dan Mosedale <dmose@mozilla.org>
|
||||
# Terry Weissman <terry@mozilla.org>
|
||||
# Dave Miller <justdave@syndicomm.com>
|
||||
|
||||
# This object models a set of relations between one item and a group
|
||||
# of other items. An example is the set of relations between one bug
|
||||
# and the users CCed on that bug. Currently, the relation objects are
|
||||
# expected to be bugzilla userids. However, this could and perhaps
|
||||
# should be generalized to work with non userid objects, such as
|
||||
# keywords associated with a bug. That shouldn't be hard to do; it
|
||||
# might involve turning this into a virtual base class, and having
|
||||
# UserSet and KeywordSet types that inherit from it.
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
# Everything that uses RelationSet should already have globals.pl loaded
|
||||
# so we don't want to load it here. Doing so causes a loop in Perl because
|
||||
# globals.pl turns around and does a 'use RelationSet'
|
||||
# See http://bugzilla.mozilla.org/show_bug.cgi?id=72862
|
||||
#require "globals.pl";
|
||||
|
||||
package RelationSet;
|
||||
use CGI::Carp qw(fatalsToBrowser);
|
||||
|
||||
# create a new empty RelationSet
|
||||
#
|
||||
sub new {
|
||||
my $type = shift();
|
||||
|
||||
# create a ref to an empty hash and bless it
|
||||
#
|
||||
my $self = {};
|
||||
bless $self, $type;
|
||||
|
||||
# construct from a comma-delimited string
|
||||
#
|
||||
if ($#_ == 0) {
|
||||
$self->mergeFromString($_[0]);
|
||||
}
|
||||
# unless this was a constructor for an empty list, somebody screwed up.
|
||||
#
|
||||
elsif ( $#_ != -1 ) {
|
||||
confess("invalid number of arguments");
|
||||
}
|
||||
|
||||
# bless as a RelationSet
|
||||
#
|
||||
return $self;
|
||||
}
|
||||
|
||||
# Assumes that the set of relations "FROM $table WHERE $constantSql and
|
||||
# $column = $value" is currently represented by $self, and this set should
|
||||
# be updated to look like $other.
|
||||
#
|
||||
# Returns an array of two strings, one INSERT and one DELETE, which will
|
||||
# make this change. Either or both strings may be the empty string,
|
||||
# meaning that no INSERT or DELETE or both (respectively) need to be done.
|
||||
#
|
||||
# THE CALLER IS RESPONSIBLE FOR ANY DESIRED LOCKING AND/OR CONSISTENCY
|
||||
# CHECKS (not to mention doing the SendSQL() calls).
|
||||
#
|
||||
sub generateSqlDeltas {
|
||||
($#_ == 5) || confess("invalid number of arguments");
|
||||
my ( $self, # instance ptr to set representing the existing state
|
||||
$endState, # instance ptr to set representing the desired state
|
||||
$table, # table where these relations are kept
|
||||
$invariantName, # column held const for a RelationSet (often "bug_id")
|
||||
$invariantValue, # what to hold the above column constant at
|
||||
$columnName # the column which varies (often a userid)
|
||||
) = @_;
|
||||
|
||||
# construct the insert list by finding relations which exist in the
|
||||
# end state but not the current state.
|
||||
#
|
||||
my @endStateRelations = keys(%$endState);
|
||||
my @insertList = ();
|
||||
foreach ( @endStateRelations ) {
|
||||
push ( @insertList, $_ ) if ( ! exists $$self{"$_"} );
|
||||
}
|
||||
|
||||
# we've built the list. If it's non-null, add required sql chrome.
|
||||
#
|
||||
my $sqlInsert="";
|
||||
if ( $#insertList > -1 ) {
|
||||
$sqlInsert = "INSERT INTO $table ($invariantName, $columnName) VALUES " .
|
||||
join (",",
|
||||
map ( "($invariantValue, $_)" , @insertList )
|
||||
);
|
||||
}
|
||||
|
||||
# construct the delete list by seeing which relations exist in the
|
||||
# current state but not the end state
|
||||
#
|
||||
my @selfRelations = keys(%$self);
|
||||
my @deleteList = ();
|
||||
foreach ( @selfRelations ) {
|
||||
push (@deleteList, $_) if ( ! exists $$endState{"$_"} );
|
||||
}
|
||||
|
||||
# we've built the list. if it's non-empty, add required sql chrome.
|
||||
#
|
||||
my $sqlDelete = "";
|
||||
if ( $#deleteList > -1 ) {
|
||||
$sqlDelete = "DELETE FROM $table WHERE $invariantName = $invariantValue " .
|
||||
"AND $columnName IN ( " . join (",", @deleteList) . " )";
|
||||
}
|
||||
|
||||
return ($sqlInsert, $sqlDelete);
|
||||
}
|
||||
|
||||
# compare the current object with another.
|
||||
#
|
||||
sub isEqual {
|
||||
($#_ == 1) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
my $other = shift();
|
||||
|
||||
# get arrays of the keys for faster processing
|
||||
#
|
||||
my @selfRelations = keys(%$self);
|
||||
my @otherRelations = keys(%$other);
|
||||
|
||||
# make sure the arrays are the same size
|
||||
#
|
||||
return 0 if ( $#selfRelations != $#otherRelations );
|
||||
|
||||
# bail out if any of the elements are different
|
||||
#
|
||||
foreach my $relation ( @selfRelations ) {
|
||||
return 0 if ( !exists $$other{$relation})
|
||||
}
|
||||
|
||||
# we made it!
|
||||
#
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# merge the results of a SQL command into this set
|
||||
#
|
||||
sub mergeFromDB {
|
||||
( $#_ == 1 ) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
|
||||
&::SendSQL(shift());
|
||||
while (my @row = &::FetchSQLData()) {
|
||||
$$self{$row[0]} = 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# merge a set in string form into this set
|
||||
#
|
||||
sub mergeFromString {
|
||||
($#_ == 1) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
|
||||
# do the merge
|
||||
#
|
||||
foreach my $person (split(/[ ,]/, shift())) {
|
||||
if ($person ne "") {
|
||||
$$self{&::DBNameToIdAndCheck($person)} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# remove a set in string form from this set
|
||||
#
|
||||
sub removeItemsInString {
|
||||
($#_ == 1) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
|
||||
# do the merge
|
||||
#
|
||||
foreach my $person (split(/[ ,]/, shift())) {
|
||||
if ($person ne "") {
|
||||
my $dbid = &::DBNameToIdAndCheck($person);
|
||||
if (exists $$self{$dbid}) {
|
||||
delete $$self{$dbid};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# remove a set in array form from this set
|
||||
#
|
||||
sub removeItemsInArray {
|
||||
($#_ > 0) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
|
||||
# do the merge
|
||||
#
|
||||
while (my $person = shift()) {
|
||||
if ($person ne "") {
|
||||
my $dbid = &::DBNameToIdAndCheck($person);
|
||||
if (exists $$self{$dbid}) {
|
||||
delete $$self{$dbid};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# return the number of elements in this set
|
||||
#
|
||||
sub size {
|
||||
my $self = shift();
|
||||
|
||||
my @k = keys(%$self);
|
||||
return $#k++;
|
||||
}
|
||||
|
||||
# return this set in array form
|
||||
#
|
||||
sub toArray {
|
||||
my $self= shift();
|
||||
|
||||
return keys(%$self);
|
||||
}
|
||||
|
||||
# return this set as an array of strings
|
||||
#
|
||||
sub toArrayOfStrings {
|
||||
($#_ == 0) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
|
||||
my @result = ();
|
||||
foreach my $i ( keys %$self ) {
|
||||
push @result, &::DBID_to_name($i);
|
||||
}
|
||||
|
||||
return sort { lc($a) cmp lc($b) } @result;
|
||||
}
|
||||
|
||||
# return this set in string form (comma-separated and sorted)
|
||||
#
|
||||
sub toString {
|
||||
($#_ == 0) || confess("invalid number of arguments");
|
||||
my $self = shift();
|
||||
|
||||
my @result = ();
|
||||
foreach my $i ( keys %$self ) {
|
||||
push @result, &::DBID_to_name($i);
|
||||
}
|
||||
|
||||
return join(',', sort(@result));
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,273 +0,0 @@
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Myk Melez <myk@mozilla.org>
|
||||
|
||||
################################################################################
|
||||
# Module Initialization
|
||||
################################################################################
|
||||
|
||||
# Make it harder for us to do dangerous things in Perl.
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
# Bundle the functions in this file together into the "Token" package.
|
||||
package Token;
|
||||
|
||||
use Date::Format;
|
||||
|
||||
# This module requires that its caller have said "require CGI.pl" to import
|
||||
# relevant functions from that script and its companion globals.pl.
|
||||
|
||||
################################################################################
|
||||
# Constants
|
||||
################################################################################
|
||||
|
||||
# The maximum number of days a token will remain valid.
|
||||
my $maxtokenage = 3;
|
||||
|
||||
################################################################################
|
||||
# Functions
|
||||
################################################################################
|
||||
|
||||
sub IssueEmailChangeToken {
|
||||
my ($userid, $old_email, $new_email) = @_;
|
||||
|
||||
my $token_ts = time();
|
||||
my $issuedate = time2str("%Y-%m-%d %H:%M", $token_ts);
|
||||
|
||||
# Generate a unique token and insert it into the tokens table.
|
||||
# We have to lock the tokens table before generating the token,
|
||||
# since the database must be queried for token uniqueness.
|
||||
&::SendSQL("LOCK TABLES tokens WRITE");
|
||||
my $token = GenerateUniqueToken();
|
||||
my $quotedtoken = &::SqlQuote($token);
|
||||
my $quoted_emails = &::SqlQuote($old_email . ":" . $new_email);
|
||||
&::SendSQL("INSERT INTO tokens ( userid , issuedate , token ,
|
||||
tokentype , eventdata )
|
||||
VALUES ( $userid , '$issuedate' , $quotedtoken ,
|
||||
'emailold' , $quoted_emails )");
|
||||
my $newtoken = GenerateUniqueToken();
|
||||
$quotedtoken = &::SqlQuote($newtoken);
|
||||
&::SendSQL("INSERT INTO tokens ( userid , issuedate , token ,
|
||||
tokentype , eventdata )
|
||||
VALUES ( $userid , '$issuedate' , $quotedtoken ,
|
||||
'emailnew' , $quoted_emails )");
|
||||
&::SendSQL("UNLOCK TABLES");
|
||||
|
||||
# Mail the user the token along with instructions for using it.
|
||||
|
||||
my $template = $::template;
|
||||
my $vars = $::vars;
|
||||
|
||||
$vars->{'oldemailaddress'} = $old_email . &::Param('emailsuffix');
|
||||
$vars->{'newemailaddress'} = $new_email . &::Param('emailsuffix');
|
||||
|
||||
$vars->{'max_token_age'} = $maxtokenage;
|
||||
$vars->{'token_ts'} = $token_ts;
|
||||
|
||||
$vars->{'token'} = $token;
|
||||
$vars->{'emailaddress'} = $old_email . &::Param('emailsuffix');
|
||||
|
||||
my $message;
|
||||
$template->process("account/email/change-old.txt.tmpl", $vars, \$message)
|
||||
|| &::ThrowTemplateError($template->error());
|
||||
|
||||
open SENDMAIL, "|/usr/lib/sendmail -t -i";
|
||||
print SENDMAIL $message;
|
||||
close SENDMAIL;
|
||||
|
||||
$vars->{'token'} = $newtoken;
|
||||
$vars->{'emailaddress'} = $new_email . &::Param('emailsuffix');
|
||||
|
||||
$message = "";
|
||||
$template->process("account/email/change-new.txt.tmpl", $vars, \$message)
|
||||
|| &::ThrowTemplateError($template->error());
|
||||
|
||||
open SENDMAIL, "|/usr/lib/sendmail -t -i";
|
||||
print SENDMAIL $message;
|
||||
close SENDMAIL;
|
||||
|
||||
}
|
||||
|
||||
sub IssuePasswordToken {
|
||||
# Generates a random token, adds it to the tokens table, and sends it
|
||||
# to the user with instructions for using it to change their password.
|
||||
|
||||
my ($loginname) = @_;
|
||||
|
||||
# Retrieve the user's ID from the database.
|
||||
my $quotedloginname = &::SqlQuote($loginname);
|
||||
&::SendSQL("SELECT userid FROM profiles WHERE login_name = $quotedloginname");
|
||||
my ($userid) = &::FetchSQLData();
|
||||
|
||||
my $token_ts = time();
|
||||
my $issuedate = time2str("%Y-%m-%d %H:%M", $token_ts);
|
||||
|
||||
# Generate a unique token and insert it into the tokens table.
|
||||
# We have to lock the tokens table before generating the token,
|
||||
# since the database must be queried for token uniqueness.
|
||||
&::SendSQL("LOCK TABLE tokens WRITE") if $::driver eq 'mysql';
|
||||
my $token = GenerateUniqueToken();
|
||||
my $quotedtoken = &::SqlQuote($token);
|
||||
my $quotedipaddr = &::SqlQuote($::ENV{'REMOTE_ADDR'});
|
||||
&::SendSQL("INSERT INTO tokens ( userid , issuedate , token , tokentype , eventdata )
|
||||
VALUES ( $userid , '$issuedate' , $quotedtoken , 'password' , $quotedipaddr )");
|
||||
&::SendSQL("UNLOCK TABLES") if $::driver eq 'mysql';
|
||||
|
||||
# Mail the user the token along with instructions for using it.
|
||||
|
||||
my $template = $::template;
|
||||
my $vars = $::vars;
|
||||
|
||||
$vars->{'token'} = $token;
|
||||
$vars->{'emailaddress'} = $loginname . &::Param('emailsuffix');
|
||||
|
||||
$vars->{'max_token_age'} = $maxtokenage;
|
||||
$vars->{'token_ts'} = $token_ts;
|
||||
|
||||
my $message = "";
|
||||
$template->process("account/password/forgotten-password.txt.tmpl",
|
||||
$vars, \$message)
|
||||
|| &::ThrowTemplateError($template->error());
|
||||
|
||||
open SENDMAIL, "|/usr/lib/sendmail -t -i";
|
||||
print SENDMAIL $message;
|
||||
close SENDMAIL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub CleanTokenTable {
|
||||
&::SendSQL("LOCK TABLES tokens WRITE") if $::driver eq 'mysql';
|
||||
if ($::driver eq 'mysql') {
|
||||
&::SendSQL("DELETE FROM tokens WHERE TO_DAYS(NOW()) - TO_DAYS(issuedate) >= " . $maxtokenage);
|
||||
} elsif ($::driver eq 'Pg') {
|
||||
&::SendSQL("DELETE FROM tokens WHERE now() - issuedate >= '$maxtokenage days'");
|
||||
}
|
||||
&::SendSQL("UNLOCK TABLES") if $::driver eq 'mysql';
|
||||
}
|
||||
|
||||
|
||||
sub GenerateUniqueToken {
|
||||
# Generates a unique random token. Uses &GenerateRandomPassword
|
||||
# for the tokens themselves and checks uniqueness by searching for
|
||||
# the token in the "tokens" table. Gives up if it can't come up
|
||||
# with a token after about one hundred tries.
|
||||
|
||||
my $token;
|
||||
my $duplicate = 1;
|
||||
my $tries = 0;
|
||||
while ($duplicate) {
|
||||
|
||||
++$tries;
|
||||
if ($tries > 100) {
|
||||
&::DisplayError("Something is seriously wrong with the token generation system.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$token = &::GenerateRandomPassword();
|
||||
&::SendSQL("SELECT userid FROM tokens WHERE token = " . &::SqlQuote($token));
|
||||
$duplicate = &::FetchSQLData();
|
||||
}
|
||||
|
||||
return $token;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub Cancel {
|
||||
# Cancels a previously issued token and notifies the system administrator.
|
||||
# This should only happen when the user accidentally makes a token request
|
||||
# or when a malicious hacker makes a token request on behalf of a user.
|
||||
|
||||
my ($token, $cancelaction) = @_;
|
||||
|
||||
# Quote the token for inclusion in SQL statements.
|
||||
my $quotedtoken = &::SqlQuote($token);
|
||||
|
||||
# Get information about the token being cancelled.
|
||||
&::SendSQL("SELECT issuedate , tokentype , eventdata , login_name , realname
|
||||
FROM tokens, profiles
|
||||
WHERE tokens.userid = profiles.userid
|
||||
AND token = $quotedtoken");
|
||||
my ($issuedate, $tokentype, $eventdata, $loginname, $realname) = &::FetchSQLData();
|
||||
|
||||
# Get the email address of the Bugzilla maintainer.
|
||||
my $maintainer = &::Param('maintainer');
|
||||
|
||||
# Format the user's real name and email address into a single string.
|
||||
my $username = $realname ? $realname . " <" . $loginname . ">" : $loginname;
|
||||
|
||||
my $template = $::template;
|
||||
my $vars = $::vars;
|
||||
|
||||
$vars->{'emailaddress'} = $username;
|
||||
$vars->{'maintainer'} = $maintainer;
|
||||
$vars->{'remoteaddress'} = $::ENV{'REMOTE_ADDR'};
|
||||
$vars->{'token'} = $token;
|
||||
$vars->{'tokentype'} = $tokentype;
|
||||
$vars->{'issuedate'} = $issuedate;
|
||||
$vars->{'eventdata'} = $eventdata;
|
||||
$vars->{'cancelaction'} = $cancelaction;
|
||||
|
||||
# Notify the user via email about the cancellation.
|
||||
|
||||
my $message;
|
||||
$template->process("account/cancel-token.txt.tmpl", $vars, \$message)
|
||||
|| &::ThrowTemplateError($template->error());
|
||||
|
||||
open SENDMAIL, "|/usr/lib/sendmail -t -i";
|
||||
print SENDMAIL $message;
|
||||
close SENDMAIL;
|
||||
|
||||
# Delete the token from the database.
|
||||
&::SendSQL("LOCK TABLE tokens WRITE") if $::driver eq 'mysql';
|
||||
&::SendSQL("DELETE FROM tokens WHERE token = $quotedtoken");
|
||||
&::SendSQL("UNLOCK TABLES") if $::driver eq 'mysql';
|
||||
}
|
||||
|
||||
sub HasPasswordToken {
|
||||
# Returns a password token if the user has one.
|
||||
|
||||
my ($userid) = @_;
|
||||
|
||||
&::SendSQL("SELECT token FROM tokens
|
||||
WHERE userid = $userid AND tokentype = 'password' LIMIT 1");
|
||||
my ($token) = &::FetchSQLData();
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
sub HasEmailChangeToken {
|
||||
# Returns an email change token if the user has one.
|
||||
|
||||
my ($userid) = @_;
|
||||
|
||||
&::SendSQL("SELECT token FROM tokens
|
||||
WHERE userid = $userid
|
||||
AND tokentype = 'emailnew'
|
||||
OR tokentype = 'emailold' LIMIT 1");
|
||||
my ($token) = &::FetchSQLData();
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
@@ -1,3 +0,0 @@
|
||||
Please consult The Bugzilla Guide for instructions on how to upgrade
|
||||
Bugzilla from an older version. The Guide can be found with this
|
||||
distribution, in docs/html, docs/txt, and docs/sgml.
|
||||
@@ -1,407 +0,0 @@
|
||||
This file contains only important changes made to Bugzilla before release
|
||||
2.8. If you are upgrading from version older than 2.8, please read this file.
|
||||
If you are upgrading from 2.8 or newer, please read the Installation and
|
||||
Upgrade instructions in The Bugzilla Guide, found with this distribution in
|
||||
docs/html, docs/txt, and docs/sgml.
|
||||
|
||||
For a complete list of what changes, use Bonsai
|
||||
(http://cvs-mirror.mozilla.org/webtools/bonsai/cvsqueryform.cgi) to
|
||||
query the CVS tree. For example,
|
||||
|
||||
http://cvs-mirror.mozilla.org/webtools/bonsai/cvsquery.cgi?module=all&branch=HEAD&branchtype=match&dir=mozilla%2Fwebtools%2Fbugzilla&file=&filetype=match&who=&whotype=match&sortby=Date&hours=2&date=week&mindate=&maxdate=&cvsroot=%2Fcvsroot
|
||||
|
||||
will tell you what has been changed in the last week.
|
||||
|
||||
|
||||
10/12/99 The CHANGES file is now obsolete! There is a new file called
|
||||
checksetup.pl. You should get in the habit of running that file every time
|
||||
you update your installation of Bugzilla. That file will be constantly
|
||||
updated to automatically update your installation to match any code changes.
|
||||
If you're curious as to what is going on, changes are commented in that file,
|
||||
at the end.
|
||||
|
||||
Many thanks to Holger Schurig <holgerschurig@nikocity.de> for writing this
|
||||
script!
|
||||
|
||||
|
||||
|
||||
10/11/99 Restructured voting database to add a cached value in each
|
||||
bug recording how many total votes that bug has. While I'm at it, I
|
||||
removed the unused "area" field from the bugs database. It is
|
||||
distressing to realize that the bugs table has reached the maximum
|
||||
number of indices allowed by MySQL (16), which may make future
|
||||
enhancements awkward.
|
||||
|
||||
You must feed the following to MySQL:
|
||||
|
||||
alter table bugs drop column area;
|
||||
alter table bugs add column votes mediumint not null, add index (votes);
|
||||
|
||||
You then *must* delete the data/versioncache file when you make this
|
||||
change, as it contains references to the "area" field. Deleting it is safe,
|
||||
bugzilla will correctly regenerate it.
|
||||
|
||||
If you have been using the voting feature at all, then you will then
|
||||
need to update the voting cache. You can do this by visiting the
|
||||
sanitycheck.cgi page, and taking it up on its offer to rebuild the
|
||||
votes stuff.
|
||||
|
||||
|
||||
10/7/99 Added voting ability. You must run the new script
|
||||
"makevotestable.sh". You must also feed the following to mysql:
|
||||
|
||||
alter table products add column votesperuser smallint not null;
|
||||
|
||||
|
||||
|
||||
9/15/99 Apparently, newer alphas of MySQL won't allow you to have
|
||||
"when" as a column name. So, I have had to rename a column in the
|
||||
bugs_activity table. You must feed the below to mysql or you won't
|
||||
work at all.
|
||||
|
||||
alter table bugs_activity change column when bug_when datetime not null;
|
||||
|
||||
|
||||
8/16/99 Added "OpenVMS" to the list of OS's. Feed this to mysql:
|
||||
|
||||
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "Mac System 8.6", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "Neutrino", "OS/2", "BeOS", "OpenVMS", "other") not null;
|
||||
|
||||
6/22/99 Added an entry to the attachments table to record who the submitter
|
||||
was. Nothing uses this yet, but it still should be recorded.
|
||||
|
||||
alter table attachments add column submitter_id mediumint not null;
|
||||
|
||||
You should also run this script to populate the new field:
|
||||
|
||||
#!/usr/bonsaitools/bin/perl -w
|
||||
use diagnostics;
|
||||
use strict;
|
||||
require "globals.pl";
|
||||
$|=1;
|
||||
ConnectToDatabase();
|
||||
SendSQL("select bug_id, attach_id from attachments order by bug_id");
|
||||
my @list;
|
||||
while (MoreSQLData()) {
|
||||
my @row = FetchSQLData();
|
||||
push(@list, \@row);
|
||||
}
|
||||
foreach my $ref (@list) {
|
||||
my ($bug, $attach) = (@$ref);
|
||||
SendSQL("select long_desc from bugs where bug_id = $bug");
|
||||
my $comment = FetchOneColumn() . "Created an attachment (id=$attach)";
|
||||
|
||||
if ($comment =~ m@-* Additional Comments From ([^ ]*)[- 0-9/:]*\nCreated an attachment \(id=$attach\)@) {
|
||||
print "Found $1\n";
|
||||
SendSQL("select userid from profiles where login_name=" .
|
||||
SqlQuote($1));
|
||||
my $userid = FetchOneColumn();
|
||||
if (defined $userid && $userid > 0) {
|
||||
SendSQL("update attachments set submitter_id=$userid where attach_id = $attach");
|
||||
}
|
||||
} else {
|
||||
print "Bug $bug can't find comment for attachment $attach\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
6/14/99 Added "BeOS" to the list of OS's. Feed this to mysql:
|
||||
|
||||
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "Mac System 8.6", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "Neutrino", "OS/2", "BeOS", "other") not null;
|
||||
|
||||
|
||||
5/27/99 Added support for dependency information. You must run the new
|
||||
"makedependenciestable.sh" script. You can turn off dependencies with the new
|
||||
"usedependencies" param, but it defaults to being on. Also, read very
|
||||
carefully the description for the new "webdotbase" param; you will almost
|
||||
certainly need to tweak it.
|
||||
|
||||
|
||||
5/24/99 Added "Mac System 8.6" and "Neutrino" to the list of OS's.
|
||||
Feed this to mysql:
|
||||
|
||||
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "Mac System 8.6", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "Neutrino", "OS/2", "other") not null;
|
||||
|
||||
|
||||
5/12/99 Added a pref to control how much email you get. This needs a new
|
||||
column in the profiles table, so feed the following to mysql:
|
||||
|
||||
alter table profiles add column emailnotification enum("ExcludeSelfChanges", "CConly", "All") not null default "ExcludeSelfChanges";
|
||||
|
||||
5/5/99 Added the ability to search by creation date. To make this perform
|
||||
well, you ought to do the following:
|
||||
|
||||
alter table bugs change column creation_ts creation_ts datetime not null, add index (creation_ts);
|
||||
|
||||
|
||||
4/30/99 Added a new severity, "blocker". To get this into your running
|
||||
Bugzilla, do the following:
|
||||
|
||||
alter table bugs change column bug_severity bug_severity enum("blocker", "critical", "major", "normal", "minor", "trivial", "enhancement") not null;
|
||||
|
||||
|
||||
4/22/99 There was a bug where the long descriptions of bugs had a variety of
|
||||
newline characters at the end, depending on the operating system of the browser
|
||||
that submitted the text. This bug has been fixed, so that no further changes
|
||||
like that will happen. But to fix problems that have already crept into your
|
||||
database, you can run the following perl script (which is slow and ugly, but
|
||||
does work:)
|
||||
#!/usr/bonsaitools/bin/perl -w
|
||||
use diagnostics;
|
||||
use strict;
|
||||
require "globals.pl";
|
||||
$|=1;
|
||||
ConnectToDatabase();
|
||||
SendSQL("select bug_id from bugs order by bug_id");
|
||||
my @list;
|
||||
while (MoreSQLData()) {
|
||||
push(@list, FetchOneColumn());
|
||||
}
|
||||
foreach my $id (@list) {
|
||||
if ($id % 50 == 0) {
|
||||
print "\n$id ";
|
||||
}
|
||||
SendSQL("select long_desc from bugs where bug_id = $id");
|
||||
my $comment = FetchOneColumn();
|
||||
my $orig = $comment;
|
||||
$comment =~ s/\r\n/\n/g; # Get rid of windows-style line endings.
|
||||
$comment =~ s/\r/\n/g; # Get rid of mac-style line endings.
|
||||
if ($comment ne $orig) {
|
||||
SendSQL("update bugs set long_desc = " . SqlQuote($comment) .
|
||||
" where bug_id = $id");
|
||||
print ".";
|
||||
} else {
|
||||
print "-";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
4/8/99 Added ability to store patches with bugs. This requires a new table
|
||||
to store the data, so you will need to run the "makeattachmenttable.sh" script.
|
||||
|
||||
3/25/99 Unfortunately, the HTML::FromText CPAN module had too many bugs, and
|
||||
so I had to roll my own. We no longer use the HTML::FromText CPAN module.
|
||||
|
||||
3/24/99 (This entry has been removed. It used to say that we required the
|
||||
HTML::FromText CPAN module, but that's no longer true.)
|
||||
|
||||
3/22/99 Added the ability to query by fields which have changed within a date
|
||||
range. To make this perform a bit better, we need a new index:
|
||||
|
||||
alter table bugs_activity add index (field);
|
||||
|
||||
3/10/99 Added 'groups' stuff, where we have different group bits that we can
|
||||
put on a person or on a bug. Some of the group bits control access to bugzilla
|
||||
features. And a person can't access a bug unless he has every group bit set
|
||||
that is also set on the bug. See the comments in makegroupstable.sh for a bit
|
||||
more info.
|
||||
|
||||
The 'maintainer' param is now used only as an email address for people to send
|
||||
complaints to. The groups table is what is now used to determine permissions.
|
||||
|
||||
You will need to run the new script "makegroupstable.sh". And then you need to
|
||||
feed the following lines to MySQL (replace XXX with the login name of the
|
||||
maintainer, the person you wish to be all-powerful).
|
||||
|
||||
alter table bugs add column groupset bigint not null;
|
||||
alter table profiles add column groupset bigint not null;
|
||||
update profiles set groupset=0x7fffffffffffffff where login_name = XXX;
|
||||
|
||||
|
||||
|
||||
3/8/99 Added params to control how priorities are set in a new bug. You can
|
||||
now choose whether to let submitters of new bugs choose a priority, or whether
|
||||
they should just accept the default priority (which is now no longer hardcoded
|
||||
to "P2", but is instead a param.) The default value of the params will cause
|
||||
the same behavior as before.
|
||||
|
||||
3/3/99 Added a "disallownew" field to the products table. If non-zero, then
|
||||
don't let people file new bugs against this product. (This is for when a
|
||||
product is retired, but you want to keep the bug reports around for posterity.)
|
||||
Feed this to MySQL:
|
||||
|
||||
alter table products add column disallownew tinyint not null;
|
||||
|
||||
|
||||
2/8/99 Added FreeBSD to the list of OS's. Feed this to MySQL:
|
||||
|
||||
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null;
|
||||
|
||||
|
||||
2/4/99 Added a new column "description" to the components table, and added
|
||||
links to a new page which will use this to describe the components of a
|
||||
given product. Feed this to MySQL:
|
||||
|
||||
alter table components add column description mediumtext not null;
|
||||
|
||||
|
||||
2/3/99 Added a new column "initialqacontact" to the components table that gives
|
||||
an initial QA contact field. It may be empty if you wish the initial qa
|
||||
contact to be empty. If you're not using the QA contact field, you don't need
|
||||
to add this column, but you might as well be safe and add it anyway:
|
||||
|
||||
alter table components add column initialqacontact tinytext not null;
|
||||
|
||||
|
||||
2/2/99 Added a new column "milestoneurl" to the products table that gives a URL
|
||||
which is to describe the currently defined milestones for a product. If you
|
||||
don't use target milestone, you might be able to get away without adding this
|
||||
column, but you might as well be safe and add it anyway:
|
||||
|
||||
alter table products add column milestoneurl tinytext not null;
|
||||
|
||||
|
||||
1/29/99 Whoops; had a misspelled op_sys. It was "Mac System 7.1.6"; it should
|
||||
be "Mac System 7.6.1". It turns out I had no bugs with this value set, so I
|
||||
could just do the below simple command. If you have bugs with this value, you
|
||||
may need to do something more complicated.
|
||||
|
||||
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null;
|
||||
|
||||
|
||||
|
||||
1/20/99 Added new fields: Target Milestone, QA Contact, and Status Whiteboard.
|
||||
These fields are all optional in the UI; there are parameters to turn them on.
|
||||
However, whether or not you use them, the fields need to be in the DB. There
|
||||
is some code that needs them, even if you don't.
|
||||
|
||||
To update your DB to have these fields, send the following to MySQL:
|
||||
|
||||
alter table bugs add column target_milestone varchar(20) not null,
|
||||
add column qa_contact mediumint not null,
|
||||
add column status_whiteboard mediumtext not null,
|
||||
add index (target_milestone), add index (qa_contact);
|
||||
|
||||
|
||||
|
||||
1/18/99 You can now query by CC. To make this perform reasonably, the CC table
|
||||
needs some indices. The following MySQL does the necessary stuff:
|
||||
|
||||
alter table cc add index (bug_id), add index (who);
|
||||
|
||||
|
||||
1/15/99 The op_sys field can now be queried by (and more easily tweaked).
|
||||
To make this perform reasonably, it needs an index. The following MySQL
|
||||
command will create the necessary index:
|
||||
|
||||
alter table bugs add index (op_sys);
|
||||
|
||||
|
||||
12/2/98 The op_sys and rep_platform fields have been tweaked. op_sys
|
||||
is now an enum, rather than having the legal values all hard-coded in
|
||||
perl. rep_platform now no longer allows a value of "X-Windows".
|
||||
|
||||
Here's how I ported to the new world. This ought to work for you too.
|
||||
Actually, it's probably overkill. I had a lot of illegal values for op_sys
|
||||
in my tables, from importing bugs from strange places. If you haven't done
|
||||
anything funky, then much of the below will be a no-op.
|
||||
|
||||
First, send the following commands to MySQL to make sure all your values for
|
||||
rep_platform and op_sys are legal in the new world..
|
||||
|
||||
update bugs set rep_platform="Sun" where rep_platform="X-Windows" and op_sys like "Solaris%";
|
||||
update bugs set rep_platform="SGI" where rep_platform="X-Windows" and op_sys = "IRIX";
|
||||
update bugs set rep_platform="SGI" where rep_platform="X-Windows" and op_sys = "HP-UX";
|
||||
update bugs set rep_platform="DEC" where rep_platform="X-Windows" and op_sys = "OSF/1";
|
||||
update bugs set rep_platform="PC" where rep_platform="X-Windows" and op_sys = "Linux";
|
||||
update bugs set rep_platform="other" where rep_platform="X-Windows";
|
||||
update bugs set rep_platform="other" where rep_platform="";
|
||||
update bugs set op_sys="Mac System 7" where op_sys="System 7";
|
||||
update bugs set op_sys="Mac System 7.5" where op_sys="System 7.5";
|
||||
update bugs set op_sys="Mac System 8.0" where op_sys="8.0";
|
||||
update bugs set op_sys="OSF/1" where op_sys="Digital Unix 4.0";
|
||||
update bugs set op_sys="IRIX" where op_sys like "IRIX %";
|
||||
update bugs set op_sys="HP-UX" where op_sys like "HP-UX %";
|
||||
update bugs set op_sys="Windows NT" where op_sys like "NT %";
|
||||
update bugs set op_sys="OSF/1" where op_sys like "OSF/1 %";
|
||||
update bugs set op_sys="Solaris" where op_sys like "Solaris %";
|
||||
update bugs set op_sys="SunOS" where op_sys like "SunOS%";
|
||||
update bugs set op_sys="other" where op_sys = "Motif";
|
||||
update bugs set op_sys="other" where op_sys = "Other";
|
||||
|
||||
Next, send the following commands to make sure you now have only legal
|
||||
entries in your table. If either of the queries do not come up empty, then
|
||||
you have to do more stuff like the above.
|
||||
|
||||
select bug_id,op_sys,rep_platform from bugs where rep_platform not regexp "^(All|DEC|HP|Macintosh|PC|SGI|Sun|X-Windows|Other)$";
|
||||
select bug_id,op_sys,rep_platform from bugs where op_sys not regexp "^(All|Windows 3.1|Windows 95|Windows 98|Windows NT|Mac System 7|Mac System 7.5|Mac System 7.1.6|Mac System 8.0|AIX|BSDI|HP-UX|IRIX|Linux|OSF/1|Solaris|SunOS|other)$";
|
||||
|
||||
Finally, once that's all clear, alter the table to make enforce the new legal
|
||||
entries:
|
||||
|
||||
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.1.6", "Mac System 8.0", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "OSF/1", "Solaris", "SunOS", "other") not null, change column rep_platform rep_platform enum("All", "DEC", "HP", "Macintosh", "PC", "SGI", "Sun", "Other");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
11/20/98 Added searching of CC field. To better support this, added
|
||||
some indexes to the CC table. You probably want to execute the following
|
||||
mysql commands:
|
||||
|
||||
alter table cc add index (bug_id);
|
||||
alter table cc add index (who);
|
||||
|
||||
|
||||
10/27/98 security check for legal products in place. bug charts are not
|
||||
available as an option if collectstats.pl has never been run. all products
|
||||
get daily stats collected now. README updated: Chart::Base is listed as
|
||||
a requirement, instructions for using collectstats.pl included as
|
||||
an optional step. also got silly and added optional quips to bug
|
||||
reports.
|
||||
|
||||
10/17/98 modified README installation instructions slightly.
|
||||
|
||||
10/7/98 Added a new table called "products". Right now, this is used
|
||||
only to have a description for each product, and that description is
|
||||
only used when initially adding a new bug. Anyway, you *must* create
|
||||
the new table (which you can do by running the new makeproducttable.sh
|
||||
script). If you just leave it empty, things will work much as they
|
||||
did before, or you can add descriptions for some or all of your
|
||||
products.
|
||||
|
||||
|
||||
9/15/98 Everything has been ported to Perl. NO MORE TCL. This
|
||||
transition should be relatively painless, except for the "params"
|
||||
file. This is the file that contains parameters you've set up on the
|
||||
editparams.cgi page. Before changing to Perl, this was a tcl-syntax
|
||||
file, stored in the same directory as the code; after the change to
|
||||
Perl, it becomes a perl-syntax file, stored in a subdirectory named
|
||||
"data". See the README file for more details on what version of Perl
|
||||
you need.
|
||||
|
||||
So, if updating from an older version of Bugzilla, you will need to
|
||||
edit data/param, change the email address listed for
|
||||
$::param{'maintainer'}, and then go revisit the editparams.cgi page
|
||||
and reset all the parameters to your taste. Fortunately, your old
|
||||
params file will still be around, and so you ought to be able to
|
||||
cut&paste important bits from there.
|
||||
|
||||
Also, note that the "whineatnews" script has changed name (it now has
|
||||
an extension of .pl instead of .tcl), so you'll need to change your
|
||||
cron job.
|
||||
|
||||
And the "comments" file has been moved to the data directory. Just do
|
||||
"cat comments >> data/comments" to restore any old comments that may
|
||||
have been lost.
|
||||
|
||||
|
||||
|
||||
9/2/98 Changed the way password validation works. We now keep a
|
||||
crypt'd version of the password in the database, and check against
|
||||
that. (This is silly, because we're also keeping the plaintext
|
||||
version there, but I have plans...) Stop passing the plaintext
|
||||
password around as a cookie; instead, we have a cookie that references
|
||||
a record in a new database table, logincookies.
|
||||
|
||||
IMPORTANT: if updating from an older version of Bugzilla, you must run
|
||||
the following commands to keep things working:
|
||||
|
||||
./makelogincookiestable.sh
|
||||
echo "alter table profiles add column cryptpassword varchar(64);" | mysql bugs
|
||||
echo "update profiles set cryptpassword = encrypt(password,substring(rand(),3, 4));" | mysql bugs
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.3 KiB |
@@ -1,792 +0,0 @@
|
||||
#!/usr/bonsaitools/bin/perl -wT
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
|
||||
################################################################################
|
||||
# Script Initialization
|
||||
################################################################################
|
||||
|
||||
# Make it harder for us to do dangerous things in Perl.
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
use lib qw(.);
|
||||
|
||||
use vars qw(
|
||||
$template
|
||||
$vars
|
||||
);
|
||||
|
||||
# Include the Bugzilla CGI and general utility library.
|
||||
require "CGI.pl";
|
||||
|
||||
# Establish a connection to the database backend.
|
||||
ConnectToDatabase();
|
||||
|
||||
# Check whether or not the user is logged in and, if so, set the $::userid
|
||||
# and $::usergroupset variables.
|
||||
quietly_check_login();
|
||||
|
||||
################################################################################
|
||||
# Main Body Execution
|
||||
################################################################################
|
||||
|
||||
# All calls to this script should contain an "action" variable whose value
|
||||
# determines what the user wants to do. The code below checks the value of
|
||||
# that variable and runs the appropriate code.
|
||||
|
||||
# Determine whether to use the action specified by the user or the default.
|
||||
my $action = $::FORM{'action'} || 'view';
|
||||
|
||||
if ($action eq "view")
|
||||
{
|
||||
validateID();
|
||||
view();
|
||||
}
|
||||
elsif ($action eq "viewall")
|
||||
{
|
||||
ValidateBugID($::FORM{'bugid'});
|
||||
viewall();
|
||||
}
|
||||
elsif ($action eq "enter")
|
||||
{
|
||||
confirm_login();
|
||||
ValidateBugID($::FORM{'bugid'});
|
||||
enter();
|
||||
}
|
||||
elsif ($action eq "insert")
|
||||
{
|
||||
confirm_login();
|
||||
ValidateBugID($::FORM{'bugid'});
|
||||
ValidateComment($::FORM{'comment'});
|
||||
validateFilename();
|
||||
validateData();
|
||||
validateDescription();
|
||||
validateIsPatch();
|
||||
validateContentType() unless $::FORM{'ispatch'};
|
||||
validateObsolete() if $::FORM{'obsolete'};
|
||||
insert();
|
||||
}
|
||||
elsif ($action eq "edit")
|
||||
{
|
||||
quietly_check_login();
|
||||
validateID();
|
||||
validateCanEdit($::FORM{'id'});
|
||||
edit();
|
||||
}
|
||||
elsif ($action eq "update")
|
||||
{
|
||||
confirm_login();
|
||||
ValidateComment($::FORM{'comment'});
|
||||
validateID();
|
||||
validateCanEdit($::FORM{'id'});
|
||||
validateDescription();
|
||||
validateIsPatch();
|
||||
validateContentType() unless $::FORM{'ispatch'};
|
||||
validateIsObsolete();
|
||||
validateStatuses();
|
||||
update();
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayError("I could not figure out what you wanted to do.")
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
################################################################################
|
||||
# Data Validation / Security Authorization
|
||||
################################################################################
|
||||
|
||||
sub validateID
|
||||
{
|
||||
# Validate the value of the "id" form field, which must contain an
|
||||
# integer that is the ID of an existing attachment.
|
||||
|
||||
detaint_natural($::FORM{'id'})
|
||||
|| DisplayError("You did not enter a valid attachment number.")
|
||||
&& exit;
|
||||
|
||||
# Make sure the attachment exists in the database.
|
||||
SendSQL("SELECT bug_id FROM attachments WHERE attach_id = $::FORM{'id'}");
|
||||
MoreSQLData()
|
||||
|| DisplayError("Attachment #$::FORM{'id'} does not exist.")
|
||||
&& exit;
|
||||
|
||||
# Make sure the user is authorized to access this attachment's bug.
|
||||
my ($bugid) = FetchSQLData();
|
||||
ValidateBugID($bugid);
|
||||
}
|
||||
|
||||
sub validateCanEdit
|
||||
{
|
||||
my ($attach_id) = (@_);
|
||||
|
||||
# If the user is not logged in, claim that they can edit. This allows
|
||||
# the edit scrren to be displayed to people who aren't logged in.
|
||||
# People not logged in can't actually commit changes, because that code
|
||||
# calls confirm_login, not quietly_check_login, before calling this sub
|
||||
return if $::userid == 0;
|
||||
|
||||
# People in editbugs can edit all attachments
|
||||
return if UserInGroup("editbugs");
|
||||
|
||||
# Bug 97729 - the submitter can edit their attachments
|
||||
SendSQL("SELECT attach_id FROM attachments WHERE " .
|
||||
"attach_id = $attach_id AND submitter_id = $::userid");
|
||||
|
||||
FetchSQLData()
|
||||
|| DisplayError("You are not authorised to edit attachment #$attach_id")
|
||||
&& exit;
|
||||
}
|
||||
|
||||
sub validateDescription
|
||||
{
|
||||
$::FORM{'description'}
|
||||
|| DisplayError("You must enter a description for the attachment.")
|
||||
&& exit;
|
||||
}
|
||||
|
||||
sub validateIsPatch
|
||||
{
|
||||
# Set the ispatch flag to zero if it is undefined, since the UI uses
|
||||
# an HTML checkbox to represent this flag, and unchecked HTML checkboxes
|
||||
# do not get sent in HTML requests.
|
||||
$::FORM{'ispatch'} = $::FORM{'ispatch'} ? 1 : 0;
|
||||
|
||||
# Set the content type to text/plain if the attachment is a patch.
|
||||
$::FORM{'contenttype'} = "text/plain" if $::FORM{'ispatch'};
|
||||
}
|
||||
|
||||
sub validateContentType
|
||||
{
|
||||
if (!$::FORM{'contenttypemethod'})
|
||||
{
|
||||
DisplayError("You must choose a method for determining the content type,
|
||||
either <em>auto-detect</em>, <em>select from list</em>, or <em>enter
|
||||
manually</em>.");
|
||||
exit;
|
||||
}
|
||||
elsif ($::FORM{'contenttypemethod'} eq 'autodetect')
|
||||
{
|
||||
# The user asked us to auto-detect the content type, so use the type
|
||||
# specified in the HTTP request headers.
|
||||
if ( !$::FILE{'data'}->{'contenttype'} )
|
||||
{
|
||||
DisplayError("You asked Bugzilla to auto-detect the content type, but
|
||||
your browser did not specify a content type when uploading the file,
|
||||
so you must enter a content type manually.");
|
||||
exit;
|
||||
}
|
||||
$::FORM{'contenttype'} = $::FILE{'data'}->{'contenttype'};
|
||||
}
|
||||
elsif ($::FORM{'contenttypemethod'} eq 'list')
|
||||
{
|
||||
# The user selected a content type from the list, so use their selection.
|
||||
$::FORM{'contenttype'} = $::FORM{'contenttypeselection'};
|
||||
}
|
||||
elsif ($::FORM{'contenttypemethod'} eq 'manual')
|
||||
{
|
||||
# The user entered a content type manually, so use their entry.
|
||||
$::FORM{'contenttype'} = $::FORM{'contenttypeentry'};
|
||||
}
|
||||
else
|
||||
{
|
||||
my $htmlcontenttypemethod = html_quote($::FORM{'contenttypemethod'});
|
||||
DisplayError("Your form submission got corrupted somehow. The <em>content
|
||||
method</em> field, which specifies how the content type gets determined,
|
||||
should have been either <em>autodetect</em>, <em>list</em>,
|
||||
or <em>manual</em>, but was instead <em>$htmlcontenttypemethod</em>.");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $::FORM{'contenttype'} !~ /^(application|audio|image|message|model|multipart|text|video)\/.+$/ )
|
||||
{
|
||||
my $htmlcontenttype = html_quote($::FORM{'contenttype'});
|
||||
DisplayError("The content type <em>$htmlcontenttype</em> is invalid.
|
||||
Valid types must be of the form <em>foo/bar</em> where <em>foo</em>
|
||||
is either <em>application, audio, image, message, model, multipart,
|
||||
text,</em> or <em>video</em>.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
sub validateIsObsolete
|
||||
{
|
||||
# Set the isobsolete flag to zero if it is undefined, since the UI uses
|
||||
# an HTML checkbox to represent this flag, and unchecked HTML checkboxes
|
||||
# do not get sent in HTML requests.
|
||||
$::FORM{'isobsolete'} = $::FORM{'isobsolete'} ? 1 : 0;
|
||||
}
|
||||
|
||||
sub validateStatuses
|
||||
{
|
||||
# Get a list of attachment statuses that are valid for this attachment.
|
||||
PushGlobalSQLState();
|
||||
SendSQL("SELECT attachstatusdefs.id
|
||||
FROM attachments, bugs, attachstatusdefs
|
||||
WHERE attachments.attach_id = $::FORM{'id'}
|
||||
AND attachments.bug_id = bugs.bug_id
|
||||
AND attachstatusdefs.product = bugs.product");
|
||||
my @statusdefs;
|
||||
push(@statusdefs, FetchSQLData()) while MoreSQLData();
|
||||
PopGlobalSQLState();
|
||||
|
||||
foreach my $status (@{$::MFORM{'status'}})
|
||||
{
|
||||
grep($_ == $status, @statusdefs)
|
||||
|| DisplayError("One of the statuses you entered is not a valid status
|
||||
for this attachment.")
|
||||
&& exit;
|
||||
# We have tested that the status is valid, so it can be detainted
|
||||
detaint_natural($status);
|
||||
}
|
||||
}
|
||||
|
||||
sub validateData
|
||||
{
|
||||
$::FORM{'data'}
|
||||
|| DisplayError("The file you are trying to attach is empty!")
|
||||
&& exit;
|
||||
|
||||
my $len = length($::FORM{'data'});
|
||||
|
||||
my $maxpatchsize = Param('maxpatchsize');
|
||||
my $maxattachmentsize = Param('maxattachmentsize');
|
||||
|
||||
# Makes sure the attachment does not exceed either the "maxpatchsize" or
|
||||
# the "maxattachmentsize" parameter.
|
||||
if ( $::FORM{'ispatch'} && $maxpatchsize && $len > $maxpatchsize*1024 )
|
||||
{
|
||||
my $lenkb = sprintf("%.0f", $len/1024);
|
||||
DisplayError("The file you are trying to attach is ${lenkb} kilobytes (KB) in size.
|
||||
Patches cannot be more than ${maxpatchsize}KB in size.
|
||||
Try breaking your patch into several pieces.");
|
||||
exit;
|
||||
} elsif ( !$::FORM{'ispatch'} && $maxattachmentsize && $len > $maxattachmentsize*1024 ) {
|
||||
my $lenkb = sprintf("%.0f", $len/1024);
|
||||
DisplayError("The file you are trying to attach is ${lenkb} kilobytes (KB) in size.
|
||||
Non-patch attachments cannot be more than ${maxattachmentsize}KB.
|
||||
If your attachment is an image, try converting it to a compressable
|
||||
format like JPG or PNG, or put it elsewhere on the web and
|
||||
link to it from the bug's URL field or in a comment on the bug.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
sub validateFilename
|
||||
{
|
||||
defined $::FILE{'data'}
|
||||
|| DisplayError("You did not specify a file to attach.")
|
||||
&& exit;
|
||||
}
|
||||
|
||||
sub validateObsolete
|
||||
{
|
||||
# Make sure the attachment id is valid and the user has permissions to view
|
||||
# the bug to which it is attached.
|
||||
foreach my $attachid (@{$::MFORM{'obsolete'}}) {
|
||||
detaint_natural($attachid)
|
||||
|| DisplayError("The attachment number of one of the attachments
|
||||
you wanted to obsolete is invalid.")
|
||||
&& exit;
|
||||
|
||||
SendSQL("SELECT bug_id, isobsolete, description
|
||||
FROM attachments WHERE attach_id = $attachid");
|
||||
|
||||
# Make sure the attachment exists in the database.
|
||||
MoreSQLData()
|
||||
|| DisplayError("Attachment #$attachid does not exist.")
|
||||
&& exit;
|
||||
|
||||
my ($bugid, $isobsolete, $description) = FetchSQLData();
|
||||
|
||||
if ($bugid != $::FORM{'bugid'})
|
||||
{
|
||||
$description = html_quote($description);
|
||||
DisplayError("Attachment #$attachid ($description) is attached
|
||||
to bug #$bugid, but you tried to flag it as obsolete while
|
||||
creating a new attachment to bug #$::FORM{'bugid'}.");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $isobsolete )
|
||||
{
|
||||
$description = html_quote($description);
|
||||
DisplayError("Attachment #$attachid ($description) is already obsolete.");
|
||||
exit;
|
||||
}
|
||||
|
||||
# Check that the user can modify this attachment
|
||||
validateCanEdit($attachid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Functions
|
||||
################################################################################
|
||||
|
||||
sub view
|
||||
{
|
||||
# Display an attachment.
|
||||
|
||||
# Retrieve the attachment content and its content type from the database.
|
||||
SendSQL("SELECT mimetype, thedata FROM attachments WHERE attach_id = $::FORM{'id'}");
|
||||
my ($contenttype, $thedata) = FetchSQLData();
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print "Content-Type: $contenttype\n\n";
|
||||
|
||||
print $thedata;
|
||||
}
|
||||
|
||||
|
||||
sub viewall
|
||||
{
|
||||
# Display all attachments for a given bug in a series of IFRAMEs within one HTML page.
|
||||
|
||||
# Retrieve the attachments from the database and write them into an array
|
||||
# of hashes where each hash represents one attachment.
|
||||
SendSQL("SELECT attach_id, creation_ts, mimetype, description, ispatch, isobsolete
|
||||
FROM attachments WHERE bug_id = $::FORM{'bugid'} ORDER BY attach_id");
|
||||
my @attachments; # the attachments array
|
||||
while (MoreSQLData())
|
||||
{
|
||||
my %a; # the attachment hash
|
||||
($a{'attachid'}, $a{'date'}, $a{'contenttype'},
|
||||
$a{'description'}, $a{'ispatch'}, $a{'isobsolete'}) = FetchSQLData();
|
||||
|
||||
# Format the attachment's creation/modification date into something readable.
|
||||
if ($a{'date'} =~ /^(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
|
||||
$a{'date'} = "$3/$4/$2 $5:$6";
|
||||
}
|
||||
|
||||
# Flag attachments as to whether or not they can be viewed (as opposed to
|
||||
# being downloaded). Currently I decide they are viewable if their MIME type
|
||||
# is either text/*, image/*, or application/vnd.mozilla.*.
|
||||
# !!! Yuck, what an ugly hack. Fix it!
|
||||
$a{'isviewable'} = ( $a{'contenttype'} =~ /^(text|image|application\/vnd\.mozilla\.)/ );
|
||||
|
||||
# Retrieve a list of status flags that have been set on the attachment.
|
||||
PushGlobalSQLState();
|
||||
SendSQL("SELECT name
|
||||
FROM attachstatuses, attachstatusdefs
|
||||
WHERE attach_id = $a{'attachid'}
|
||||
AND attachstatuses.statusid = attachstatusdefs.id
|
||||
ORDER BY sortkey");
|
||||
my @statuses;
|
||||
push(@statuses, FetchSQLData()) while MoreSQLData();
|
||||
$a{'statuses'} = \@statuses;
|
||||
PopGlobalSQLState();
|
||||
|
||||
# Add the hash representing the attachment to the array of attachments.
|
||||
push @attachments, \%a;
|
||||
}
|
||||
|
||||
# Retrieve the bug summary for displaying on screen.
|
||||
SendSQL("SELECT short_desc FROM bugs WHERE bug_id = $::FORM{'bugid'}");
|
||||
my ($bugsummary) = FetchSQLData();
|
||||
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'bugid'} = $::FORM{'bugid'};
|
||||
$vars->{'bugsummary'} = $bugsummary;
|
||||
$vars->{'attachments'} = \@attachments;
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("attachment/show-multiple.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
|
||||
sub enter
|
||||
{
|
||||
# Display a form for entering a new attachment.
|
||||
|
||||
# Retrieve the attachments the user can edit from the database and write
|
||||
# them into an array of hashes where each hash represents one attachment.
|
||||
my $canEdit = "";
|
||||
if (!UserInGroup("editbugs")) {
|
||||
$canEdit = "AND submitter_id = $::userid";
|
||||
}
|
||||
SendSQL("SELECT attach_id, description
|
||||
FROM attachments
|
||||
WHERE bug_id = $::FORM{'bugid'}
|
||||
AND isobsolete = 0 $canEdit
|
||||
ORDER BY attach_id");
|
||||
my @attachments; # the attachments array
|
||||
while ( MoreSQLData() ) {
|
||||
my %a; # the attachment hash
|
||||
($a{'id'}, $a{'description'}) = FetchSQLData();
|
||||
|
||||
# Add the hash representing the attachment to the array of attachments.
|
||||
push @attachments, \%a;
|
||||
}
|
||||
|
||||
# Retrieve the bug summary for displaying on screen.
|
||||
SendSQL("SELECT short_desc FROM bugs WHERE bug_id = $::FORM{'bugid'}");
|
||||
my ($bugsummary) = FetchSQLData();
|
||||
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'bugid'} = $::FORM{'bugid'};
|
||||
$vars->{'bugsummary'} = $bugsummary;
|
||||
$vars->{'attachments'} = \@attachments;
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("attachment/create.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
|
||||
sub insert
|
||||
{
|
||||
# Insert a new attachment into the database.
|
||||
|
||||
# Escape characters in strings that will be used in SQL statements.
|
||||
my $filename = SqlQuote($::FILE{'data'}->{'filename'});
|
||||
my $description = SqlQuote($::FORM{'description'});
|
||||
my $contenttype = SqlQuote($::FORM{'contenttype'});
|
||||
my $thedata = SqlQuote($::FORM{'data'});
|
||||
|
||||
# Insert the attachment into the database.
|
||||
SendSQL("INSERT INTO attachments (bug_id, filename, description, mimetype, ispatch, submitter_id, thedata)
|
||||
VALUES ($::FORM{'bugid'}, $filename, $description, $contenttype, $::FORM{'ispatch'}, $::userid, $thedata)");
|
||||
|
||||
# Retrieve the ID of the newly created attachment record.
|
||||
SendSQL("SELECT LAST_INSERT_ID()");
|
||||
my $attachid = FetchOneColumn();
|
||||
|
||||
# Insert a comment about the new attachment into the database.
|
||||
my $comment = "Created an attachment (id=$attachid)\n$::FORM{'description'}\n";
|
||||
$comment .= ("\n" . $::FORM{'comment'}) if $::FORM{'comment'};
|
||||
|
||||
use Text::Wrap;
|
||||
$Text::Wrap::columns = 80;
|
||||
$Text::Wrap::huge = 'overflow';
|
||||
$comment = Text::Wrap::wrap('', '', $comment);
|
||||
|
||||
AppendComment($::FORM{'bugid'},
|
||||
$::COOKIE{"Bugzilla_login"},
|
||||
$comment);
|
||||
|
||||
# Make existing attachments obsolete.
|
||||
my $fieldid = GetFieldID('attachments.isobsolete');
|
||||
foreach my $attachid (@{$::MFORM{'obsolete'}}) {
|
||||
SendSQL("UPDATE attachments SET isobsolete = 1 WHERE attach_id = $attachid");
|
||||
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
|
||||
VALUES ($::FORM{'bugid'}, $attachid, $::userid, NOW(), $fieldid, '0', '1')");
|
||||
}
|
||||
|
||||
# Send mail to let people know the attachment has been created. Uses a
|
||||
# special syntax of the "open" and "exec" commands to capture the output of
|
||||
# "processmail", which "system" doesn't allow, without running the command
|
||||
# through a shell, which backticks (``) do.
|
||||
#system ("./processmail", $bugid , $::userid);
|
||||
#my $mailresults = `./processmail $bugid $::userid`;
|
||||
my $mailresults = '';
|
||||
open(PMAIL, "-|") or exec('./processmail', $::FORM{'bugid'}, $::COOKIE{'Bugzilla_login'});
|
||||
$mailresults .= $_ while <PMAIL>;
|
||||
close(PMAIL);
|
||||
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'bugid'} = $::FORM{'bugid'};
|
||||
$vars->{'attachid'} = $attachid;
|
||||
$vars->{'description'} = $description;
|
||||
$vars->{'mailresults'} = $mailresults;
|
||||
$vars->{'contenttypemethod'} = $::FORM{'contenttypemethod'};
|
||||
$vars->{'contenttype'} = $::FORM{'contenttype'};
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("attachment/created.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
|
||||
sub edit
|
||||
{
|
||||
# Edit an attachment record. Users with "editbugs" privileges, (or the
|
||||
# original attachment's submitter) can edit the attachment's description,
|
||||
# content type, ispatch and isobsolete flags, and statuses, and they can
|
||||
# also submit a comment that appears in the bug.
|
||||
# Users cannot edit the content of the attachment itself.
|
||||
|
||||
# Retrieve the attachment from the database.
|
||||
SendSQL("SELECT description, mimetype, bug_id, ispatch, isobsolete
|
||||
FROM attachments WHERE attach_id = $::FORM{'id'}");
|
||||
my ($description, $contenttype, $bugid, $ispatch, $isobsolete) = FetchSQLData();
|
||||
|
||||
# Flag attachment as to whether or not it can be viewed (as opposed to
|
||||
# being downloaded). Currently I decide it is viewable if its content
|
||||
# type is either text/.* or application/vnd.mozilla.*.
|
||||
# !!! Yuck, what an ugly hack. Fix it!
|
||||
my $isviewable = ( $contenttype =~ /^(text|image|application\/vnd\.mozilla\.)/ );
|
||||
|
||||
# Retrieve a list of status flags that have been set on the attachment.
|
||||
my %statuses;
|
||||
SendSQL("SELECT id, name
|
||||
FROM attachstatuses JOIN attachstatusdefs
|
||||
WHERE attachstatuses.statusid = attachstatusdefs.id
|
||||
AND attach_id = $::FORM{'id'}");
|
||||
while ( my ($id, $name) = FetchSQLData() )
|
||||
{
|
||||
$statuses{$id} = $name;
|
||||
}
|
||||
|
||||
# Retrieve a list of statuses for this bug's product, and build an array
|
||||
# of hashes in which each hash is a status flag record.
|
||||
# ???: Move this into versioncache or its own routine?
|
||||
my @statusdefs;
|
||||
SendSQL("SELECT id, name
|
||||
FROM attachstatusdefs, bugs
|
||||
WHERE bug_id = $bugid
|
||||
AND attachstatusdefs.product = bugs.product
|
||||
ORDER BY sortkey");
|
||||
while ( MoreSQLData() )
|
||||
{
|
||||
my ($id, $name) = FetchSQLData();
|
||||
push @statusdefs, { 'id' => $id , 'name' => $name };
|
||||
}
|
||||
|
||||
# Retrieve a list of attachments for this bug as well as a summary of the bug
|
||||
# to use in a navigation bar across the top of the screen.
|
||||
SendSQL("SELECT attach_id FROM attachments WHERE bug_id = $bugid ORDER BY attach_id");
|
||||
my @bugattachments;
|
||||
push(@bugattachments, FetchSQLData()) while (MoreSQLData());
|
||||
SendSQL("SELECT short_desc FROM bugs WHERE bug_id = $bugid");
|
||||
my ($bugsummary) = FetchSQLData();
|
||||
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'attachid'} = $::FORM{'id'};
|
||||
$vars->{'description'} = $description;
|
||||
$vars->{'contenttype'} = $contenttype;
|
||||
$vars->{'bugid'} = $bugid;
|
||||
$vars->{'bugsummary'} = $bugsummary;
|
||||
$vars->{'ispatch'} = $ispatch;
|
||||
$vars->{'isobsolete'} = $isobsolete;
|
||||
$vars->{'isviewable'} = $isviewable;
|
||||
$vars->{'statuses'} = \%statuses;
|
||||
$vars->{'statusdefs'} = \@statusdefs;
|
||||
$vars->{'attachments'} = \@bugattachments;
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("attachment/edit.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
|
||||
sub update
|
||||
{
|
||||
# Update an attachment record.
|
||||
|
||||
# Get the bug ID for the bug to which this attachment is attached.
|
||||
SendSQL("SELECT bug_id FROM attachments WHERE attach_id = $::FORM{'id'}");
|
||||
my $bugid = FetchSQLData()
|
||||
|| DisplayError("Cannot figure out bug number.")
|
||||
&& exit;
|
||||
|
||||
# Lock database tables in preparation for updating the attachment.
|
||||
if ($::driver eq 'mysql') {
|
||||
SendSQL("LOCK TABLES attachments WRITE , attachstatuses WRITE ,
|
||||
attachstatusdefs READ , fielddefs READ , bugs_activity WRITE");
|
||||
}
|
||||
|
||||
# Get a copy of the attachment record before we make changes
|
||||
# so we can record those changes in the activity table.
|
||||
SendSQL("SELECT description, mimetype, ispatch, isobsolete
|
||||
FROM attachments WHERE attach_id = $::FORM{'id'}");
|
||||
my ($olddescription, $oldcontenttype, $oldispatch, $oldisobsolete) = FetchSQLData();
|
||||
|
||||
# Get the list of old status flags.
|
||||
SendSQL("SELECT attachstatusdefs.name
|
||||
FROM attachments, attachstatuses, attachstatusdefs
|
||||
WHERE attachments.attach_id = $::FORM{'id'}
|
||||
AND attachments.attach_id = attachstatuses.attach_id
|
||||
AND attachstatuses.statusid = attachstatusdefs.id
|
||||
ORDER BY attachstatusdefs.sortkey
|
||||
");
|
||||
my @oldstatuses;
|
||||
while (MoreSQLData()) {
|
||||
push(@oldstatuses, FetchSQLData());
|
||||
}
|
||||
my $oldstatuslist = join(', ', @oldstatuses);
|
||||
|
||||
# Update the database with the new status flags.
|
||||
SendSQL("DELETE FROM attachstatuses WHERE attach_id = $::FORM{'id'}");
|
||||
foreach my $statusid (@{$::MFORM{'status'}})
|
||||
{
|
||||
SendSQL("INSERT INTO attachstatuses (attach_id, statusid) VALUES ($::FORM{'id'}, $statusid)");
|
||||
}
|
||||
|
||||
# Get the list of new status flags.
|
||||
SendSQL("SELECT attachstatusdefs.name
|
||||
FROM attachments, attachstatuses, attachstatusdefs
|
||||
WHERE attachments.attach_id = $::FORM{'id'}
|
||||
AND attachments.attach_id = attachstatuses.attach_id
|
||||
AND attachstatuses.statusid = attachstatusdefs.id
|
||||
ORDER BY attachstatusdefs.sortkey
|
||||
");
|
||||
my @newstatuses;
|
||||
while (MoreSQLData()) {
|
||||
push(@newstatuses, FetchSQLData());
|
||||
}
|
||||
my $newstatuslist = join(', ', @newstatuses);
|
||||
|
||||
# Quote the description and content type for use in the SQL UPDATE statement.
|
||||
my $quoteddescription = SqlQuote($::FORM{'description'});
|
||||
my $quotedcontenttype = SqlQuote($::FORM{'contenttype'});
|
||||
|
||||
# Update the attachment record in the database.
|
||||
# Sets the creation timestamp to itself to avoid it being updated automatically.
|
||||
SendSQL("UPDATE attachments
|
||||
SET description = $quoteddescription ,
|
||||
mimetype = $quotedcontenttype ,
|
||||
ispatch = $::FORM{'ispatch'} ,
|
||||
isobsolete = $::FORM{'isobsolete'} ,
|
||||
creation_ts = creation_ts
|
||||
WHERE attach_id = $::FORM{'id'}
|
||||
");
|
||||
|
||||
# Record changes in the activity table.
|
||||
if ($olddescription ne $::FORM{'description'}) {
|
||||
my $quotedolddescription = SqlQuote($olddescription);
|
||||
my $fieldid = GetFieldID('attachments.description');
|
||||
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
|
||||
VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $quotedolddescription, $quoteddescription)");
|
||||
}
|
||||
if ($oldcontenttype ne $::FORM{'contenttype'}) {
|
||||
my $quotedoldcontenttype = SqlQuote($oldcontenttype);
|
||||
my $fieldid = GetFieldID('attachments.mimetype');
|
||||
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
|
||||
VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $quotedoldcontenttype, $quotedcontenttype)");
|
||||
}
|
||||
if ($oldispatch ne $::FORM{'ispatch'}) {
|
||||
my $fieldid = GetFieldID('attachments.ispatch');
|
||||
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
|
||||
VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $oldispatch, $::FORM{'ispatch'})");
|
||||
}
|
||||
if ($oldisobsolete ne $::FORM{'isobsolete'}) {
|
||||
my $fieldid = GetFieldID('attachments.isobsolete');
|
||||
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
|
||||
VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $oldisobsolete, $::FORM{'isobsolete'})");
|
||||
}
|
||||
if ($oldstatuslist ne $newstatuslist) {
|
||||
my ($removed, $added) = DiffStrings($oldstatuslist, $newstatuslist);
|
||||
my $quotedremoved = SqlQuote($removed);
|
||||
my $quotedadded = SqlQuote($added);
|
||||
my $fieldid = GetFieldID('attachstatusdefs.name');
|
||||
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
|
||||
VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $quotedremoved, $quotedadded)");
|
||||
}
|
||||
|
||||
# Unlock all database tables now that we are finished updating the database.
|
||||
if ($::driver eq 'mysql') {
|
||||
SendSQL("UNLOCK TABLES");
|
||||
}
|
||||
|
||||
# If this installation has enabled the request manager, let the manager know
|
||||
# an attachment was updated so it can check for requests on that attachment
|
||||
# and fulfill them. The request manager allows users to request database
|
||||
# changes of other users and tracks the fulfillment of those requests. When
|
||||
# an attachment record is updated and the request manager is called, it will
|
||||
# fulfill those requests that were requested of the user performing the update
|
||||
# which are requests for the attachment being updated.
|
||||
#my $requests;
|
||||
#if (Param('userequestmanager'))
|
||||
#{
|
||||
# use Request;
|
||||
# # Specify the fieldnames that have been updated.
|
||||
# my @fieldnames = ('description', 'mimetype', 'status', 'ispatch', 'isobsolete');
|
||||
# # Fulfill pending requests.
|
||||
# $requests = Request::fulfillRequest('attachment', $::FORM{'id'}, @fieldnames);
|
||||
# $vars->{'requests'} = $requests;
|
||||
#}
|
||||
|
||||
# If the user submitted a comment while editing the attachment,
|
||||
# add the comment to the bug.
|
||||
if ( $::FORM{'comment'} )
|
||||
{
|
||||
use Text::Wrap;
|
||||
$Text::Wrap::columns = 80;
|
||||
$Text::Wrap::huge = 'wrap';
|
||||
|
||||
# Append a string to the comment to let users know that the comment came from
|
||||
# the "edit attachment" screen.
|
||||
my $comment = qq|(From update of attachment $::FORM{'id'})\n| . $::FORM{'comment'};
|
||||
|
||||
my $wrappedcomment = "";
|
||||
foreach my $line (split(/\r\n|\r|\n/, $comment))
|
||||
{
|
||||
if ( $line =~ /^>/ )
|
||||
{
|
||||
$wrappedcomment .= $line . "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$wrappedcomment .= wrap('', '', $line) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Get the user's login name since the AppendComment function needs it.
|
||||
my $who = DBID_to_name($::userid);
|
||||
# Mention $::userid again so Perl doesn't give me a warning about it.
|
||||
my $neverused = $::userid;
|
||||
|
||||
# Append the comment to the list of comments in the database.
|
||||
AppendComment($bugid, $who, $wrappedcomment);
|
||||
|
||||
}
|
||||
|
||||
# Send mail to let people know the bug has changed. Uses a special syntax
|
||||
# of the "open" and "exec" commands to capture the output of "processmail",
|
||||
# which "system" doesn't allow, without running the command through a shell,
|
||||
# which backticks (``) do.
|
||||
#system ("./processmail", $bugid , $::userid);
|
||||
#my $mailresults = `./processmail $bugid $::userid`;
|
||||
my $mailresults = '';
|
||||
open(PMAIL, "-|") or exec('./processmail', $bugid, DBID_to_name($::userid));
|
||||
$mailresults .= $_ while <PMAIL>;
|
||||
close(PMAIL);
|
||||
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'attachid'} = $::FORM{'id'};
|
||||
$vars->{'bugid'} = $bugid;
|
||||
$vars->{'mailresults'} = $mailresults;
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("attachment/updated.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
# Dave Miller <justdave@syndicomm.com>
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
use RelationSet;
|
||||
|
||||
# Use the Attachment module to display attachments for the bug.
|
||||
use Attachment;
|
||||
|
||||
sub show_bug {
|
||||
# Shut up misguided -w warnings about "used only once". For some reason,
|
||||
# "use vars" chokes on me when I try it here.
|
||||
sub bug_form_pl_sillyness {
|
||||
my $zz;
|
||||
$zz = %::FORM;
|
||||
$zz = %::proddesc;
|
||||
$zz = %::prodmaxvotes;
|
||||
$zz = @::enterable_products;
|
||||
$zz = @::settable_resolution;
|
||||
$zz = $::unconfirmedstate;
|
||||
$zz = $::milestoneurl;
|
||||
$zz = $::template;
|
||||
$zz = $::vars;
|
||||
$zz = @::legal_priority;
|
||||
$zz = @::legal_platform;
|
||||
$zz = @::legal_severity;
|
||||
$zz = @::legal_bug_status;
|
||||
$zz = @::target_milestone;
|
||||
$zz = @::components;
|
||||
$zz = @::legal_keywords;
|
||||
$zz = @::versions;
|
||||
$zz = @::legal_opsys;
|
||||
}
|
||||
|
||||
# Use templates
|
||||
my $template = $::template;
|
||||
my $vars = $::vars;
|
||||
|
||||
$vars->{'GetBugLink'} = \&GetBugLink;
|
||||
$vars->{'quoteUrls'} = \"eUrls,
|
||||
$vars->{'lsearch'} = \&lsearch,
|
||||
$vars->{'header_done'} = (@_),
|
||||
|
||||
quietly_check_login();
|
||||
|
||||
my $id = $::FORM{'id'};
|
||||
|
||||
if (!defined($id)) {
|
||||
$template->process("bug/choose.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
exit;
|
||||
}
|
||||
|
||||
my %user = %{$vars->{'user'}};
|
||||
my %bug;
|
||||
|
||||
# Populate the bug hash with the info we get directly from the DB.
|
||||
my $query = "
|
||||
SELECT
|
||||
bugs.bug_id,
|
||||
product,
|
||||
version,
|
||||
rep_platform,
|
||||
op_sys,
|
||||
bug_status,
|
||||
resolution,
|
||||
priority,
|
||||
bug_severity,
|
||||
component,
|
||||
assigned_to,
|
||||
reporter,
|
||||
bug_file_loc,
|
||||
short_desc,
|
||||
target_milestone,
|
||||
qa_contact,
|
||||
status_whiteboard, ";
|
||||
|
||||
if ($::driver eq 'mysql') {
|
||||
$query .= "
|
||||
date_format(creation_ts, '%Y-%m-%d %H:%i'),
|
||||
groupset,
|
||||
delta_ts, ";
|
||||
} elsif ($::driver eq 'Pg') {
|
||||
$query .= "
|
||||
TO_CHAR(creation_ts, 'YYYY-MM-DD HH24:MI:SS'),
|
||||
groupset,
|
||||
TO_CHAR(delta_ts, 'YYYYMMDDHH24MISS'), ";
|
||||
}
|
||||
|
||||
$query .= "
|
||||
SUM(votes.count)
|
||||
FROM
|
||||
bugs LEFT JOIN votes USING(bug_id)
|
||||
WHERE
|
||||
bugs.bug_id = $id
|
||||
GROUP BY
|
||||
bugs.bug_id,
|
||||
product,
|
||||
version,
|
||||
rep_platform,
|
||||
op_sys,
|
||||
bug_status,
|
||||
resolution,
|
||||
priority,
|
||||
bug_severity,
|
||||
component,
|
||||
assigned_to,
|
||||
reporter,
|
||||
bug_file_loc,
|
||||
short_desc,
|
||||
target_milestone,
|
||||
qa_contact,
|
||||
status_whiteboard,
|
||||
creation_ts,
|
||||
groupset,
|
||||
delta_ts ";
|
||||
|
||||
SendSQL($query);
|
||||
|
||||
my $value;
|
||||
my @row = FetchSQLData();
|
||||
foreach my $field ("bug_id", "product", "version", "rep_platform",
|
||||
"op_sys", "bug_status", "resolution", "priority",
|
||||
"bug_severity", "component", "assigned_to", "reporter",
|
||||
"bug_file_loc", "short_desc", "target_milestone",
|
||||
"qa_contact", "status_whiteboard", "creation_ts",
|
||||
"groupset", "delta_ts", "votes")
|
||||
{
|
||||
$value = shift(@row);
|
||||
$bug{$field} = defined($value) ? $value : "";
|
||||
}
|
||||
|
||||
# General arrays of info about the database state
|
||||
GetVersionTable();
|
||||
|
||||
# Fiddle the product list.
|
||||
my $seen_curr_prod;
|
||||
my @prodlist;
|
||||
|
||||
foreach my $product (@::enterable_products) {
|
||||
if ($product eq $bug{'product'}) {
|
||||
# if it's the product the bug is already in, it's ALWAYS in
|
||||
# the popup, period, whether the user can see it or not, and
|
||||
# regardless of the disallownew setting.
|
||||
$seen_curr_prod = 1;
|
||||
push(@prodlist, $product);
|
||||
next;
|
||||
}
|
||||
|
||||
if (Param("usebuggroupsentry")
|
||||
&& GroupExists($product)
|
||||
&& !UserInGroup($product))
|
||||
{
|
||||
# If we're using bug groups to restrict entry on products, and
|
||||
# this product has a bug group, and the user is not in that
|
||||
# group, we don't want to include that product in this list.
|
||||
next;
|
||||
}
|
||||
|
||||
push(@prodlist, $product);
|
||||
}
|
||||
|
||||
# The current product is part of the popup, even if new bugs are no longer
|
||||
# allowed for that product
|
||||
if (!$seen_curr_prod) {
|
||||
push (@prodlist, $bug{'product'});
|
||||
@prodlist = sort @prodlist;
|
||||
}
|
||||
|
||||
$vars->{'product'} = \@prodlist;
|
||||
$vars->{'rep_platform'} = \@::legal_platform;
|
||||
$vars->{'priority'} = \@::legal_priority;
|
||||
$vars->{'bug_severity'} = \@::legal_severity;
|
||||
$vars->{'op_sys'} = \@::legal_opsys;
|
||||
$vars->{'bug_status'} = \@::legal_bug_status;
|
||||
|
||||
# Hack - this array contains "" for some reason. See bug 106589.
|
||||
shift @::settable_resolution;
|
||||
$vars->{'resolution'} = \@::settable_resolution;
|
||||
|
||||
$vars->{'component_'} = $::components{$bug{'product'}};
|
||||
$vars->{'version'} = $::versions{$bug{'product'}};
|
||||
$vars->{'target_milestone'} = $::target_milestone{$bug{'product'}};
|
||||
$bug{'milestoneurl'} = $::milestoneurl{$bug{'product'}} ||
|
||||
"notargetmilestone.html";
|
||||
|
||||
$vars->{'use_votes'} = $::prodmaxvotes{$bug{'product'}};
|
||||
|
||||
# Add additional, calculated fields to the bug hash
|
||||
if (@::legal_keywords) {
|
||||
$vars->{'use_keywords'} = 1;
|
||||
|
||||
SendSQL("SELECT keyworddefs.name
|
||||
FROM keyworddefs, keywords
|
||||
WHERE keywords.bug_id = $id
|
||||
AND keyworddefs.id = keywords.keywordid
|
||||
ORDER BY keyworddefs.name");
|
||||
my @keywords;
|
||||
while (MoreSQLData()) {
|
||||
push(@keywords, FetchOneColumn());
|
||||
}
|
||||
|
||||
$bug{'keywords'} = \@keywords;
|
||||
}
|
||||
|
||||
# Attachments
|
||||
$bug{'attachments'} = Attachment::query($id);
|
||||
|
||||
# Dependencies
|
||||
my @list;
|
||||
SendSQL("SELECT dependson FROM dependencies WHERE
|
||||
blocked = $id ORDER BY dependson");
|
||||
while (MoreSQLData()) {
|
||||
my ($i) = FetchSQLData();
|
||||
push(@list, $i);
|
||||
}
|
||||
|
||||
$bug{'dependson'} = \@list;
|
||||
|
||||
my @list2;
|
||||
SendSQL("SELECT blocked FROM dependencies WHERE
|
||||
dependson = $id ORDER BY blocked");
|
||||
while (MoreSQLData()) {
|
||||
my ($i) = FetchSQLData();
|
||||
push(@list2, $i);
|
||||
}
|
||||
|
||||
$bug{'blocked'} = \@list2;
|
||||
|
||||
# Groups
|
||||
my @groups;
|
||||
if ($::usergroupset ne '0' || $bug{'groupset'} ne '0') {
|
||||
my $bug_groupset = $bug{'groupset'};
|
||||
|
||||
if ($::driver eq 'mysql') {
|
||||
SendSQL("select bit, name, description, (bit & $bug{'groupset'} != 0), " .
|
||||
"(bit & $::usergroupset != 0) from groups where isbuggroup != 0 " .
|
||||
# Include active groups as well as inactive groups to which
|
||||
# the bug already belongs. This way the bug can be removed
|
||||
# from an inactive group but can only be added to active ones.
|
||||
"and ((isactive = 1 or (bit & $bug{'groupset'} != 0)) or " .
|
||||
"(bit & $bug{'groupset'} != 0)) " .
|
||||
"order by description");
|
||||
} elsif ($::driver eq 'Pg') {
|
||||
SendSQL("select group_bit, name, description, (group_bit & int8($bug{'groupset'}) != 0), " .
|
||||
"(group_bit & int8($::usergroupset) != 0) from groups where isbuggroup != 0 " .
|
||||
# Include active groups as well as inactive groups to which
|
||||
# the bug already belongs. This way the bug can be removed
|
||||
# from an inactive group but can only be added to active ones.
|
||||
"and ((isactive = 1 or (group_bit & int8($bug{'groupset'}) != 0)) or " .
|
||||
"(group_bit & int8($bug{'groupset'}) != 0)) " .
|
||||
"order by description");
|
||||
}
|
||||
|
||||
$user{'inallgroups'} = 1;
|
||||
|
||||
while (MoreSQLData()) {
|
||||
my ($bit, $name, $description, $ison, $ingroup) = FetchSQLData();
|
||||
# For product groups, we only want to display the checkbox if either
|
||||
# (1) The bit is already set, or
|
||||
# (2) The user is in the group, but either:
|
||||
# (a) The group is a product group for the current product, or
|
||||
# (b) The group name isn't a product name
|
||||
# This means that all product groups will be skipped, but
|
||||
# non-product bug groups will still be displayed.
|
||||
if($ison ||
|
||||
($ingroup && (($name eq $bug{'product'}) ||
|
||||
(!defined $::proddesc{$name}))))
|
||||
{
|
||||
$user{'inallgroups'} &= $ingroup;
|
||||
|
||||
push (@groups, { "bit" => $bit,
|
||||
"ison" => $ison,
|
||||
"ingroup" => $ingroup,
|
||||
"description" => $description });
|
||||
}
|
||||
}
|
||||
|
||||
# If the bug is restricted to a group, display checkboxes that allow
|
||||
# the user to set whether or not the reporter
|
||||
# and cc list can see the bug even if they are not members of all
|
||||
# groups to which the bug is restricted.
|
||||
if ($bug{'groupset'} != 0) {
|
||||
$bug{'inagroup'} = 1;
|
||||
|
||||
# Determine whether or not the bug is always accessible by the
|
||||
# reporter, QA contact, and/or users on the cc: list.
|
||||
SendSQL("SELECT reporter_accessible, cclist_accessible
|
||||
FROM bugs
|
||||
WHERE bug_id = $id
|
||||
");
|
||||
($bug{'reporter_accessible'},
|
||||
$bug{'cclist_accessible'}) = FetchSQLData();
|
||||
}
|
||||
}
|
||||
$vars->{'groups'} = \@groups;
|
||||
|
||||
my $movers = Param("movers");
|
||||
$user{'canmove'} = Param("move-enabled")
|
||||
&& (defined $::COOKIE{"Bugzilla_login"})
|
||||
&& ($::COOKIE{"Bugzilla_login"} =~ /\Q$movers\E/);
|
||||
|
||||
# User permissions
|
||||
|
||||
# In the below, if the person hasn't logged in ($::userid == 0), then
|
||||
# we treat them as if they can do anything. That's because we don't
|
||||
# know why they haven't logged in; it may just be because they don't
|
||||
# use cookies. Display everything as if they have all the permissions
|
||||
# in the world; their permissions will get checked when they log in
|
||||
# and actually try to make the change.
|
||||
$user{'canedit'} = $::userid == 0
|
||||
|| $::userid == $bug{'reporter'}
|
||||
|| $::userid == $bug{'qa_contact'}
|
||||
|| $::userid == $bug{'assigned_to'}
|
||||
|| UserInGroup("editbugs");
|
||||
$user{'canconfirm'} = ($::userid == 0) || UserInGroup("canconfirm");
|
||||
|
||||
# Bug states
|
||||
$bug{'isunconfirmed'} = ($bug{'bug_status'} eq $::unconfirmedstate);
|
||||
$bug{'isopened'} = IsOpenedState($bug{'bug_status'});
|
||||
|
||||
# People involved with the bug
|
||||
$bug{'assigned_to_email'} = DBID_to_name($bug{'assigned_to'});
|
||||
$bug{'assigned_to'} = DBID_to_real_or_loginname($bug{'assigned_to'});
|
||||
$bug{'reporter'} = DBID_to_real_or_loginname($bug{'reporter'});
|
||||
$bug{'qa_contact'} = $bug{'qa_contact'} > 0 ?
|
||||
DBID_to_name($bug{'qa_contact'}) : "";
|
||||
|
||||
my $ccset = new RelationSet;
|
||||
$ccset->mergeFromDB("SELECT who FROM cc WHERE bug_id=$id");
|
||||
|
||||
my @cc = $ccset->toArrayOfStrings();
|
||||
$bug{'cc'} = \@cc if $cc[0];
|
||||
|
||||
# Next bug in list (if there is one)
|
||||
my @bug_list;
|
||||
if ($::COOKIE{"BUGLIST"} && $id)
|
||||
{
|
||||
@bug_list = split(/:/, $::COOKIE{"BUGLIST"});
|
||||
}
|
||||
$vars->{'bug_list'} = \@bug_list;
|
||||
|
||||
$bug{'comments'} = GetComments($bug{'bug_id'});
|
||||
|
||||
# This is length in number of comments
|
||||
$bug{'longdesclength'} = scalar(@{$bug{'comments'}});
|
||||
|
||||
# Add the bug and user hashes to the variables
|
||||
$vars->{'bug'} = \%bug;
|
||||
$vars->{'user'} = \%user;
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("bug/edit.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,206 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<HTML>
|
||||
|
||||
<!--
|
||||
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 Bugzilla Bug Tracking System.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape Communications
|
||||
Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
-->
|
||||
|
||||
<head>
|
||||
<TITLE>A Bug's Life Cycle</TITLE>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 ALIGN=CENTER>A Bug's Life Cycle</h1>
|
||||
|
||||
The <B>status</B> and <B>resolution</B> field define and track the
|
||||
life cycle of a bug.
|
||||
|
||||
<a name="status"></a>
|
||||
<p>
|
||||
<TABLE BORDER=1 CELLPADDING=4>
|
||||
|
||||
<TR ALIGN=CENTER VALIGN=TOP>
|
||||
<TD WIDTH="50%"><H1>STATUS</H1> <TD><H1>RESOLUTION</H1>
|
||||
|
||||
<TR VALIGN=TOP>
|
||||
<TD>The <B>status</B> field indicates the general health of a bug. Only
|
||||
certain status transitions are allowed.
|
||||
<TD>The <b>resolution</b> field indicates what happened to this bug.
|
||||
|
||||
<TR VALIGN=TOP><TD>
|
||||
<DL><DT><B>
|
||||
<A HREF="confirmhelp.html">UNCONFIRMED</A></B>
|
||||
<DD> This bug has recently been added to the database. Nobody has
|
||||
validated that this bug is true. Users who have the "canconfirm"
|
||||
permission set may confirm this bug, changing its state to NEW.
|
||||
Or, it may be directly resolved and marked RESOLVED.
|
||||
<DT><B>NEW</B>
|
||||
<DD> This bug has recently been added to the assignee's list of bugs
|
||||
and must be processed. Bugs in this state may be accepted, and
|
||||
become <B>ASSIGNED</B>, passed on to someone else, and remain
|
||||
<B>NEW</B>, or resolved and marked <B>RESOLVED</B>.
|
||||
<DT><B>ASSIGNED</B>
|
||||
<DD> This bug is not yet resolved, but is assigned to the proper
|
||||
person. From here bugs can be given to another person and become
|
||||
<B>NEW</B>, or resolved and become <B>RESOLVED</B>.
|
||||
<DT><B>REOPENED</B>
|
||||
<DD>This bug was once resolved, but the resolution was deemed
|
||||
incorrect. For example, a <B>WORKSFORME</B> bug is
|
||||
<B>REOPENED</B> when more information shows up and the bug is now
|
||||
reproducible. From here bugs are either marked <B>ASSIGNED</B>
|
||||
or <B>RESOLVED</B>.
|
||||
</DL>
|
||||
<TD>
|
||||
<DL>
|
||||
<DD> No resolution yet. All bugs which are in one of these "open" states
|
||||
have the resolution set to blank. All other bugs
|
||||
will be marked with one of the following resolutions.
|
||||
</DL>
|
||||
|
||||
<TR VALIGN=TOP><TD>
|
||||
<DL>
|
||||
<DT><B>RESOLVED</B>
|
||||
<DD> A resolution has been taken, and it is awaiting verification by
|
||||
QA. From here bugs are either re-opened and become
|
||||
<B>REOPENED</B>, are marked <B>VERIFIED</B>, or are closed for good
|
||||
and marked <B>CLOSED</B>.
|
||||
<DT><B>VERIFIED</B>
|
||||
<DD> QA has looked at the bug and the resolution and agrees that the
|
||||
appropriate resolution has been taken. Bugs remain in this state
|
||||
until the product they were reported against actually ships, at
|
||||
which point they become <B>CLOSED</B>.
|
||||
<DT><B>CLOSED</B>
|
||||
<DD> The bug is considered dead, the resolution is correct. Any zombie
|
||||
bugs who choose to walk the earth again must do so by becoming
|
||||
<B>REOPENED</B>.
|
||||
</DL>
|
||||
|
||||
<TD>
|
||||
<DL>
|
||||
<DT><B>FIXED</B>
|
||||
<DD> A fix for this bug is checked into the tree and tested.
|
||||
<DT><B>INVALID</B>
|
||||
<DD> The problem described is not a bug
|
||||
<DT><B>WONTFIX</B>
|
||||
<DD> The problem described is a bug which will never be fixed.
|
||||
<DT><B>LATER</B>
|
||||
<DD> The problem described is a bug which will not be fixed in this
|
||||
version of the product.
|
||||
<DT><B>REMIND</B>
|
||||
<DD> The problem described is a bug which will probably not be fixed in this
|
||||
version of the product, but might still be.
|
||||
<DT><B>DUPLICATE</B>
|
||||
<DD> The problem is a duplicate of an existing bug. Marking a bug
|
||||
duplicate requires the bug# of the duplicating bug and will at
|
||||
least put that bug number in the description field.
|
||||
<DT><B>WORKSFORME</B>
|
||||
<DD> All attempts at reproducing this bug were futile, reading the
|
||||
code produces no clues as to why this behavior would occur. If
|
||||
more information appears later, please re-assign the bug, for
|
||||
now, file it.
|
||||
</DL>
|
||||
</TABLE>
|
||||
|
||||
<H1>Other Fields</H1>
|
||||
|
||||
<table border=1 cellpadding=4><tr><td>
|
||||
<h2><a name="severity">Severity</a></h2>
|
||||
|
||||
This field describes the impact of a bug.
|
||||
|
||||
<p>
|
||||
<p>
|
||||
|
||||
<table>
|
||||
<tr><th>Blocker</th><td>Blocks development and/or testing work
|
||||
<tr><th>Critical</th><td>crashes, loss of data, severe memory leak
|
||||
<tr><th>Major</th><td>major loss of function
|
||||
<tr><th>Minor</th><td>minor loss of function, or other problem where easy workaround is present
|
||||
<tr><th>Trivial</th><td>cosmetic problem like misspelled words or misaligned text
|
||||
<tr><th>Enhancement</th><td>Request for enhancement
|
||||
</table>
|
||||
|
||||
</td><td>
|
||||
|
||||
<h2><a name="priority">Priority</a></h2>
|
||||
|
||||
This field describes the importance and order in which a bug should be
|
||||
fixed. This field is utilized by the programmers/engineers to
|
||||
prioritize their work to be done. The available priorities are:
|
||||
|
||||
<p>
|
||||
<p>
|
||||
|
||||
<table>
|
||||
<tr><th>P1</th><td>Most important
|
||||
<tr><th>P2</th><td>
|
||||
<tr><th>P3</th><td>
|
||||
<tr><th>P4</th><td>
|
||||
<tr><th>P5</th><td>Least important
|
||||
</table>
|
||||
</tr></table>
|
||||
|
||||
<h2><a name="rep_platform">Platform</a></h2>
|
||||
This is the hardware platform against which the bug was reported. Legal
|
||||
platforms include:
|
||||
|
||||
<UL>
|
||||
<LI> All (happens on all platform; cross-platform bug)
|
||||
<LI> Macintosh
|
||||
<LI> PC
|
||||
<LI> Sun
|
||||
<LI> HP
|
||||
</UL>
|
||||
|
||||
<b>Note:</b> Selecting the option "All" does not select bugs assigned against all platforms. It
|
||||
merely selects bugs that <b>occur</b> on all platforms.
|
||||
|
||||
<h2><a name="op_sys">Operating System</a></h2>
|
||||
This is the operating system against which the bug was reported. Legal
|
||||
operating systems include:
|
||||
|
||||
<UL>
|
||||
<LI> All (happens on all operating systems; cross-platform bug)
|
||||
<LI> Windows 95
|
||||
<LI> Mac System 8.0
|
||||
<LI> Linux
|
||||
</UL>
|
||||
|
||||
Note that the operating system implies the platform, but not always.
|
||||
For example, Linux can run on PC and Macintosh and others.
|
||||
|
||||
<h2><a name="assigned_to">Assigned To</a></h2>
|
||||
|
||||
This is the person in charge of resolving the bug. Every time this
|
||||
field changes, the status changes to <B>NEW</B> to make it easy to see
|
||||
which new bugs have appeared on a person's list.
|
||||
|
||||
The default status for queries is set to NEW, ASSIGNED and REOPENED. When
|
||||
searching for bugs that have been resolved or verified, remember to set the
|
||||
status field appropriately.
|
||||
|
||||
<hr>
|
||||
<!-- hhmts start -->
|
||||
Last modified: Sun Apr 14 12:51:23 EST 2002
|
||||
<!-- hhmts end -->
|
||||
</body> </html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,392 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||||
<title>Bug Writing Guidelines</title>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<h1>Bug Writing Guidelines</h1>
|
||||
</center>
|
||||
|
||||
<h3>Why You Should Read This</h3>
|
||||
|
||||
<blockquote>
|
||||
<p>Simply put, the more effectively you report a bug, the more
|
||||
likely an engineer will actually fix it.</p>
|
||||
|
||||
<p>These guidelines are a general
|
||||
tutorial to teach novice and intermediate bug reporters how to compose effective bug reports. Not every sentence may precisely apply to
|
||||
your software project.</p>
|
||||
</blockquote>
|
||||
|
||||
<h3>How to Write a Useful Bug Report</h3>
|
||||
|
||||
<blockquote>
|
||||
<p>Useful bug reports are ones that get bugs fixed. A useful bug
|
||||
report normally has two qualities:</p>
|
||||
|
||||
<ol>
|
||||
<li><b>Reproducible.</b> If an engineer can't see the bug herself to prove that it exists, she'll probably stamp your bug report "WORKSFORME" or "INVALID" and move on to the next bug. Every detail you can provide helps.<br>
|
||||
<br>
|
||||
</li>
|
||||
|
||||
<li><b>Specific.</b> The quicker the engineer can isolate the bug
|
||||
to a specific area, the more likely she'll expediently fix it.
|
||||
(If a programmer or tester has to decypher a bug, they may spend
|
||||
more time cursing the submitter than solving the problem.)
|
||||
<br>
|
||||
<br>
|
||||
[ <a href="#tips" name="Anchor">Tell Me More</a> ]
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>Let's say the application you're testing is a web browser. You
|
||||
crash at foo.com, and want to write up a bug report:</p>
|
||||
|
||||
<blockquote>
|
||||
<p><b>BAD:</b> "My browser crashed. I think I was on www.foo.com. I play golf with Bill Gates, so you better fix this problem, or I'll report you to him. By the way, your Back icon looks like a squashed rodent. UGGGLY. And my grandmother's home page is all messed up in your browser. Thx 4 UR help."
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>GOOD:</b> "I crashed each time I went to www.foo.com, using
|
||||
the 2002-02-25 build on a Windows 2000 system. I also
|
||||
rebooted into Linux, and reproduced this problem using the 2002-02-24
|
||||
Linux build.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It again crashed each time upon drawing the Foo banner at the top
|
||||
of the page. I broke apart the page, and discovered that the
|
||||
following image link will crash the application reproducibly,
|
||||
unless you remove the "border=0" attribute:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<tt><IMG SRC="http://www.foo.com/images/topics/topicfoos.gif"
|
||||
width="34" height="44" border="0" alt="News"></tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>How to Enter your Useful Bug Report into Bugzilla:</h3>
|
||||
|
||||
<blockquote>
|
||||
<p>Before you enter your bug, use Bugzilla's
|
||||
<a href="query.cgi">search page</a> to determine whether the defect you've discovered is a known, already-reported bug. If your bug is the 37th duplicate of a known issue, you're more likely to annoy the engineer. (Annoyed
|
||||
engineers fix fewer bugs.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Next, be sure to reproduce your bug using a recent
|
||||
build. Engineers tend to be most interested in problems affecting
|
||||
the code base that they're actively working on. After all, the bug you're reporting
|
||||
may already be fixed.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you've discovered a new bug using a current build, report it in
|
||||
Bugzilla:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>From your Bugzilla main page, choose
|
||||
"<a href="enter_bug.cgi">Enter a new bug</a>".</li>
|
||||
|
||||
<li>Select the product that you've found a bug in.</li>
|
||||
|
||||
<li>Enter your e-mail address, password, and press the "Login"
|
||||
button. (If you don't yet have a password, leave the password field empty,
|
||||
and press the "E-mail me a password" button instead.
|
||||
You'll quickly receive an e-mail message with your password.)</li>
|
||||
</ol>
|
||||
|
||||
<p>Now, fill out the form. Here's what it all means:</p>
|
||||
|
||||
<p><b>Where did you find the bug?</b></p>
|
||||
|
||||
<blockquote>
|
||||
<p><b>Product: In which product did you find the bug?</b><br>
|
||||
You just specified this on the last page, so you can't edit it here.</p>
|
||||
|
||||
<p><b>Version: In which product version did you find the
|
||||
bug?</b><br>
|
||||
(If applicable)</p>
|
||||
|
||||
<p><b>Component: In which component does the bug exist?</b><br>
|
||||
Bugzilla requires that you select a component to enter a bug. (Not sure which to choose?
|
||||
Click on the Component link. You'll see a description of each component, to help you make the best choice.)</p>
|
||||
|
||||
<p><b>OS: On which Operating System (OS) did you find this bug?</b>
|
||||
(e.g. Linux, Windows 2000, Mac OS 9.)<br>
|
||||
If you know the bug happens on all OSs, choose 'All'. Otherwise,
|
||||
select the OS that you found the bug on, or "Other" if your OS
|
||||
isn't listed.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>How important is the bug?</b></p>
|
||||
|
||||
<blockquote>
|
||||
<p><b>Severity: How damaging is the bug?</b><br>
|
||||
This item defaults to 'normal'. If you're not sure what severity your bug deserves, click on the Severity link.
|
||||
You'll see a description of each severity rating. <br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Who will be following up on the bug?</b></p>
|
||||
|
||||
<blockquote>
|
||||
<p><b>Assigned To: Which engineer should be responsible for fixing
|
||||
this bug?</b><br>
|
||||
Bugzilla will automatically assign the bug to a default engineer
|
||||
upon submitting a bug report. If you'd prefer to directly assign the bug to
|
||||
someone else, enter their e-mail address into this field. (To see the list of
|
||||
default engineers for each component, click on the Component
|
||||
link.)</p>
|
||||
|
||||
<p><b>Cc: Who else should receive e-mail updates on changes to this
|
||||
bug?</b><br>
|
||||
List the full e-mail addresses of other individuals who should
|
||||
receive an e-mail update upon every change to the bug report. You
|
||||
can enter as many e-mail addresses as you'd like, separated by spaces or commas, as long as those
|
||||
people have Bugzilla accounts.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>What else can you tell the engineer about the bug?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>Summary:</b> <b>How would you describe the bug, in
|
||||
approximately 60 or fewer characters?</b><br>
|
||||
A good summary should <b>quickly and uniquely identify a bug
|
||||
report</b>. Otherwise, an engineer cannot meaningfully identify
|
||||
your bug by its summary, and will often fail to pay attention to
|
||||
your bug report when skimming through a 10 page bug list.<br>
|
||||
<br>
|
||||
A useful summary might be
|
||||
"<tt>PCMCIA install fails on Tosh Tecra 780DVD w/ 3c589C</tt>".
|
||||
"<tt>Software fails</tt>" or "<tt>install problem</tt>" would be
|
||||
examples of a bad summary.<br>
|
||||
<br>
|
||||
[ <a href="#summary">Tell Me More</a> ]<br>
|
||||
<br>
|
||||
<b>Description: </b><br>
|
||||
Please provide a detailed problem report in this field.
|
||||
Your bug's recipients will most likely expect the following information:</p>
|
||||
|
||||
<blockquote>
|
||||
<p><b>Overview Description:</b> More detailed expansion of
|
||||
summary.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Drag-selecting any page crashes Mac builds in NSGetFactory
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Steps to Reproduce:</b> Minimized, easy-to-follow steps that will
|
||||
trigger the bug. Include any special setup steps.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
1) View any web page. (I used the default sample page,
|
||||
resource:/res/samples/test0.html)
|
||||
|
||||
2) Drag-select the page. (Specifically, while holding down
|
||||
the mouse button, drag the mouse pointer downwards from any
|
||||
point in the browser's content region to the bottom of the
|
||||
browser's content region.)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<b>Actual Results:</b> What the application did after performing
|
||||
the above steps.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
The application crashed. Stack crawl appended below from MacsBug.
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Expected Results:</b> What the application should have done,
|
||||
were the bug not present.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
The window should scroll downwards. Scrolled content should be selected.
|
||||
(Or, at least, the application should not crash.)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Build Date & Platform:</b> Date and platform of the build
|
||||
that you first encountered the bug in.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Build 2002-03-15 on Mac OS 9.0
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Additional Builds and Platforms:</b> Whether or not the bug
|
||||
takes place on other platforms (or browsers, if applicable).</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
- Also Occurs On
|
||||
Mozilla (2002-03-15 build on Windows NT 4.0)
|
||||
|
||||
- Doesn't Occur On
|
||||
Mozilla (2002-03-15 build on Red Hat Linux; feature not supported)
|
||||
Internet Explorer 5.0 (shipping build on Windows NT 4.0)
|
||||
Netscape Communicator 4.5 (shipping build on Mac OS 9.0)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Additional Information:</b> Any other debugging information.
|
||||
For crashing bugs:</p>
|
||||
|
||||
<ul>
|
||||
<li><b>Win32:</b> if you receive a Dr. Watson error, please note
|
||||
the type of the crash, and the module that the application crashed
|
||||
in. (e.g. access violation in apprunner.exe)</li>
|
||||
|
||||
<li><b>Mac OS:</b> if you're running MacsBug, please provide the
|
||||
results of a <b>how</b> and an <b>sc</b>:</li>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
*** MACSBUG STACK CRAWL OF CRASH (Mac OS)
|
||||
Calling chain using A6/R1 links
|
||||
Back chain ISA Caller
|
||||
00000000 PPC 0BA85E74
|
||||
03AEFD80 PPC 0B742248
|
||||
03AEFD30 PPC 0B50FDDC NSGetFactory+027FC
|
||||
PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0
|
||||
</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<p>You're done!<br>
|
||||
<br>
|
||||
After double-checking your entries for any possible errors, press
|
||||
the "Commit" button, and your bug report will now be in the
|
||||
Bugzilla database.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
<h3>More Information on Writing Good Bugs</h3>
|
||||
|
||||
<blockquote>
|
||||
<p><b><a name="tips"></a> 1. General Tips for a Useful Bug
|
||||
Report</b>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Use an explicit structure, so your bug reports are easy to
|
||||
skim.</b> Bug report users often need immediate access to specific
|
||||
sections of your bug. If your Bugzilla installation supports the
|
||||
Bugzilla Helper, use it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Avoid cuteness if it costs clarity.</b> Nobody will be laughing
|
||||
at your funny bug title at 3:00 AM when they can't remember how to
|
||||
find your bug.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>One bug per report.</b> Completely different people typically
|
||||
fix, verify, and prioritize different bugs. If you mix a handful of
|
||||
bugs into a single report, the right people probably won't discover
|
||||
your bugs in a timely fashion, or at all. Certain bugs are also
|
||||
more important than others. It's impossible to prioritize a bug
|
||||
report when it contains four different issues, all of differing
|
||||
importance.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>No bug is too trivial to report.</b> Unless you're reading the
|
||||
source code, you can't see actual software bugs, like a dangling
|
||||
pointer -- you'll see their visible manifestations, such as the
|
||||
segfault when the application finally crashes. Severe software
|
||||
problems can manifest themselves in superficially trivial ways.
|
||||
File them anyway.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b><a name="summary"></a>2. How and Why to Write Good Bug Summaries</b>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p><b>You want to make a good first impression on the bug
|
||||
recipient.</b> Just like a New York Times headline guides readers
|
||||
towards a relevant article from dozens of choices, will your bug summary
|
||||
suggest that your bug report is worth reading from dozens or hundreds of
|
||||
choices?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Conversely, a vague bug summary like <tt>install problem</tt> forces anyone
|
||||
reviewing installation bugs to waste time opening up your bug to
|
||||
determine whether it matters.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Your bug will often be searched by its summary.</b> Just as
|
||||
you'd find web pages with Google by searching by keywords through
|
||||
intuition, so will other people locate your bugs. Descriptive bug
|
||||
summaries are naturally keyword-rich, and easier to find.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, you'll find a bug titled "<tt>Dragging icons from List View to
|
||||
gnome-terminal doesn't paste path</tt>" if you search on "List",
|
||||
"terminal", or "path". Those search keywords wouldn't have found a
|
||||
bug titled "<tt>Dragging icons
|
||||
doesn't paste</tt>".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ask yourself, "Would someone understand my bug from just this
|
||||
summary?" If so, you've written a fine summary.
|
||||
</p>
|
||||
|
||||
<p><b>Don't write titles like these:</b></p>
|
||||
|
||||
<ol>
|
||||
<li>"Can't install" - Why can't you install? What happens when you
|
||||
try to install?</li>
|
||||
<li>"Severe Performance Problems" - ...and they occur when you do
|
||||
what?</li>
|
||||
<li>"back button does not work" - Ever? At all?</li>
|
||||
</ol>
|
||||
|
||||
<p><b>Good bug titles:</b></p>
|
||||
<ol>
|
||||
<li>"1.0 upgrade installation fails if Mozilla M18 package present"
|
||||
- Explains problem and the context.</li>
|
||||
<li>"RPM 4 installer crashes if launched on Red Hat 6.2 (RPM 3)
|
||||
system" - Explains what happens, and the context.</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<p>(Written and maintained by
|
||||
<a href="http://www.prometheus-music.com/eli">Eli Goldberg</a>. Claudius
|
||||
Gayle, Gervase Markham, Peter Mock, Chris Pratt, Tom Schutter and Chris Yeh also
|
||||
contributed significant changes. Constructive
|
||||
<a href="mailto:eli@prometheus-music.com">suggestions</a> welcome.)</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
<!ELEMENT bugzilla (bug+)>
|
||||
<!ATTLIST bugzilla
|
||||
version CDATA #REQUIRED
|
||||
urlbase CDATA #REQUIRED
|
||||
maintainer CDATA #REQUIRED
|
||||
exporter CDATA #IMPLIED
|
||||
>
|
||||
<!ELEMENT bug (bug_id, (bug_status, product, priority, version, rep_platform, assigned_to, delta_ts, component, reporter, target_milestone?, bug_severity, creation_ts, qa_contact?, op_sys, resolution?, bug_file_loc?, short_desc?, keywords*, status_whiteboard?, dependson*, blocks*, cc*, long_desc*, attachment*)?)>
|
||||
<!ATTLIST bug
|
||||
error (NotFound | NotPermitted | InvalidBugId) #IMPLIED
|
||||
>
|
||||
<!ELEMENT bug_id (#PCDATA)>
|
||||
<!ELEMENT exporter (#PCDATA)>
|
||||
<!ELEMENT urlbase (#PCDATA)>
|
||||
<!ELEMENT bug_status (#PCDATA)>
|
||||
<!ELEMENT product (#PCDATA)>
|
||||
<!ELEMENT priority (#PCDATA)>
|
||||
<!ELEMENT version (#PCDATA)>
|
||||
<!ELEMENT rep_platform (#PCDATA)>
|
||||
<!ELEMENT assigned_to (#PCDATA)>
|
||||
<!ELEMENT delta_ts (#PCDATA)>
|
||||
<!ELEMENT component (#PCDATA)>
|
||||
<!ELEMENT reporter (#PCDATA)>
|
||||
<!ELEMENT target_milestone (#PCDATA)>
|
||||
<!ELEMENT bug_severity (#PCDATA)>
|
||||
<!ELEMENT creation_ts (#PCDATA)>
|
||||
<!ELEMENT qa_contact (#PCDATA)>
|
||||
<!ELEMENT status_whiteboard (#PCDATA)>
|
||||
<!ELEMENT op_sys (#PCDATA)>
|
||||
<!ELEMENT resolution (#PCDATA)>
|
||||
<!ELEMENT bug_file_loc (#PCDATA)>
|
||||
<!ELEMENT short_desc (#PCDATA)>
|
||||
<!ELEMENT keywords (#PCDATA)>
|
||||
<!ELEMENT dependson (#PCDATA)>
|
||||
<!ELEMENT blocks (#PCDATA)>
|
||||
<!ELEMENT cc (#PCDATA)>
|
||||
<!ELEMENT long_desc (who, bug_when, thetext)>
|
||||
<!ELEMENT who (#PCDATA)>
|
||||
<!ELEMENT bug_when (#PCDATA)>
|
||||
<!ELEMENT thetext (#PCDATA)>
|
||||
<!ELEMENT attachment (attachid, date, desc, type?, data?)>
|
||||
<!ELEMENT attachid (#PCDATA)>
|
||||
<!ELEMENT date (#PCDATA)>
|
||||
<!ELEMENT desc (#PCDATA)>
|
||||
<!ELEMENT type (#PCDATA)>
|
||||
<!ELEMENT data (#PCDATA)>
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bonsaitools/bin/perl -wT
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
|
||||
use strict;
|
||||
|
||||
print q{Content-type: text/html
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Refresh"
|
||||
CONTENT="0; URL=userprefs.cgi">
|
||||
</HEAD>
|
||||
<BODY>
|
||||
This URL is obsolete. Forwarding you to the correct one.
|
||||
<P>
|
||||
Going to <A HREF="userprefs.cgi">userprefs.cgi</A>
|
||||
<BR>
|
||||
</BODY>
|
||||
</HTML>
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,124 +0,0 @@
|
||||
#!/usr/bonsaitools/bin/perl -wT
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
use lib qw(.);
|
||||
|
||||
use vars qw(
|
||||
@legal_keywords
|
||||
$buffer
|
||||
$template
|
||||
$vars
|
||||
);
|
||||
|
||||
require "CGI.pl";
|
||||
|
||||
print "Content-type: text/html\n";
|
||||
|
||||
# The master list not only says what fields are possible, but what order
|
||||
# they get displayed in.
|
||||
|
||||
ConnectToDatabase();
|
||||
GetVersionTable();
|
||||
|
||||
my @masterlist = ("opendate", "changeddate", "severity", "priority",
|
||||
"platform", "owner", "reporter", "status", "resolution",
|
||||
"product", "component", "version", "os", "votes");
|
||||
|
||||
if (Param("usetargetmilestone")) {
|
||||
push(@masterlist, "target_milestone");
|
||||
}
|
||||
if (Param("useqacontact")) {
|
||||
push(@masterlist, "qa_contact");
|
||||
}
|
||||
if (Param("usestatuswhiteboard")) {
|
||||
push(@masterlist, "status_whiteboard");
|
||||
}
|
||||
if (@::legal_keywords) {
|
||||
push(@masterlist, "keywords");
|
||||
}
|
||||
|
||||
|
||||
push(@masterlist, ("summary", "summaryfull"));
|
||||
|
||||
$vars->{masterlist} = \@masterlist;
|
||||
|
||||
my @collist;
|
||||
if (defined $::FORM{'rememberedquery'}) {
|
||||
my $splitheader = 0;
|
||||
if (defined $::FORM{'resetit'}) {
|
||||
@collist = @::default_column_list;
|
||||
} else {
|
||||
foreach my $i (@masterlist) {
|
||||
if (defined $::FORM{"column_$i"}) {
|
||||
push @collist, $i;
|
||||
}
|
||||
}
|
||||
if (exists $::FORM{'splitheader'}) {
|
||||
$splitheader = $::FORM{'splitheader'};
|
||||
}
|
||||
}
|
||||
my $list = join(" ", @collist);
|
||||
my $urlbase = Param("urlbase");
|
||||
my $cookiepath = Param("cookiepath");
|
||||
print "Set-Cookie: COLUMNLIST=$list ; path=$cookiepath ; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
|
||||
print "Set-Cookie: SPLITHEADER=$::FORM{'splitheader'} ; path=$cookiepath ; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
|
||||
print "Refresh: 0; URL=buglist.cgi?$::FORM{'rememberedquery'}\n";
|
||||
print "\n";
|
||||
print "<META HTTP-EQUIV=Refresh CONTENT=\"1; URL=$urlbase"."buglist.cgi?$::FORM{'rememberedquery'}\">\n";
|
||||
print "<TITLE>What a hack.</TITLE>\n";
|
||||
PutHeader ("Change columns");
|
||||
print "Resubmitting your query with new columns...\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (defined $::COOKIE{'COLUMNLIST'}) {
|
||||
@collist = split(/ /, $::COOKIE{'COLUMNLIST'});
|
||||
} else {
|
||||
@collist = @::default_column_list;
|
||||
}
|
||||
|
||||
$vars->{collist} = \@collist;
|
||||
|
||||
$vars->{splitheader} = 0;
|
||||
if ($::COOKIE{'SPLITHEADER'}) {
|
||||
$vars->{splitheader} = 1;
|
||||
}
|
||||
|
||||
my %desc = ();
|
||||
foreach my $i (@masterlist) {
|
||||
$desc{$i} = $i;
|
||||
}
|
||||
|
||||
$desc{'summary'} = "Summary (first 60 characters)";
|
||||
$desc{'summaryfull'} = "Full Summary";
|
||||
|
||||
$vars->{desc} = \%desc;
|
||||
$vars->{buffer} = $::buffer;
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
print "Content-type: text/html\n\n";
|
||||
$template->process("list/change-columns.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
#!/usr/bonsaitools/bin/perl -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>,
|
||||
# Harrison Page <harrison@netscape.com>
|
||||
# Gervase Markham <gerv@gerv.net>
|
||||
|
||||
# Run me out of cron at midnight to collect Bugzilla statistics.
|
||||
|
||||
|
||||
use AnyDBM_File;
|
||||
use diagnostics;
|
||||
use strict;
|
||||
use vars @::legal_product;
|
||||
|
||||
require "globals.pl";
|
||||
|
||||
# tidy up after graphing module
|
||||
if (chdir("graphs")) {
|
||||
unlink <./*.gif>;
|
||||
unlink <./*.png>;
|
||||
chdir("..");
|
||||
}
|
||||
|
||||
ConnectToDatabase(1);
|
||||
GetVersionTable();
|
||||
|
||||
my @myproducts;
|
||||
push( @myproducts, "-All-", @::legal_product );
|
||||
|
||||
foreach (@myproducts) {
|
||||
my $dir = "data/mining";
|
||||
|
||||
&check_data_dir ($dir);
|
||||
&collect_stats ($dir, $_);
|
||||
}
|
||||
|
||||
&calculate_dupes();
|
||||
|
||||
sub check_data_dir {
|
||||
my $dir = shift;
|
||||
|
||||
if (! -d) {
|
||||
mkdir $dir, 0777;
|
||||
chmod 0777, $dir;
|
||||
}
|
||||
}
|
||||
|
||||
sub collect_stats {
|
||||
my $dir = shift;
|
||||
my $product = shift;
|
||||
my $when = localtime (time);
|
||||
|
||||
# NB: Need to mangle the product for the filename, but use the real
|
||||
# product name in the query
|
||||
my $file_product = $product;
|
||||
$file_product =~ s/\//-/gs;
|
||||
my $file = join '/', $dir, $file_product;
|
||||
my $exists = -f $file;
|
||||
|
||||
if (open DATA, ">>$file") {
|
||||
push my @row, &today;
|
||||
|
||||
foreach my $status ('NEW', 'ASSIGNED', 'REOPENED', 'UNCONFIRMED', 'RESOLVED', 'VERIFIED', 'CLOSED') {
|
||||
if( $product eq "-All-" ) {
|
||||
SendSQL("select count(bug_status) from bugs where bug_status='$status'");
|
||||
} else {
|
||||
SendSQL("select count(bug_status) from bugs where bug_status='$status' and product='$product'");
|
||||
}
|
||||
|
||||
push @row, FetchOneColumn();
|
||||
}
|
||||
|
||||
foreach my $resolution ('FIXED', 'INVALID', 'WONTFIX', 'LATER', 'REMIND', 'DUPLICATE', 'WORKSFORME', 'MOVED') {
|
||||
if( $product eq "-All-" ) {
|
||||
SendSQL("select count(resolution) from bugs where resolution='$resolution'");
|
||||
} else {
|
||||
SendSQL("select count(resolution) from bugs where resolution='$resolution' and product='$product'");
|
||||
}
|
||||
|
||||
push @row, FetchOneColumn();
|
||||
}
|
||||
|
||||
if (! $exists) {
|
||||
print DATA <<FIN;
|
||||
# Bugzilla Daily Bug Stats
|
||||
#
|
||||
# Do not edit me! This file is generated.
|
||||
#
|
||||
# fields: DATE|NEW|ASSIGNED|REOPENED|UNCONFIRMED|RESOLVED|VERIFIED|CLOSED|FIXED|INVALID|WONTFIX|LATER|REMIND|DUPLICATE|WORKSFORME|MOVED
|
||||
# Product: $product
|
||||
# Created: $when
|
||||
FIN
|
||||
}
|
||||
|
||||
print DATA (join '|', @row) . "\n";
|
||||
close DATA;
|
||||
} else {
|
||||
print "$0: $file, $!";
|
||||
}
|
||||
}
|
||||
|
||||
sub calculate_dupes {
|
||||
SendSQL("SELECT * FROM duplicates");
|
||||
|
||||
my %dupes;
|
||||
my %count;
|
||||
my @row;
|
||||
my $key;
|
||||
my $changed = 1;
|
||||
|
||||
my $today = &today_dash;
|
||||
|
||||
# Save % count here in a date-named file
|
||||
# so we can read it back in to do changed counters
|
||||
# First, delete it if it exists, so we don't add to the contents of an old file
|
||||
if (my @files = <data/duplicates/dupes$today*>) {
|
||||
unlink @files;
|
||||
}
|
||||
|
||||
dbmopen(%count, "data/duplicates/dupes$today", 0644) || die "Can't open DBM dupes file: $!";
|
||||
|
||||
# Create a hash with key "a bug number", value "bug which that bug is a
|
||||
# direct dupe of" - straight from the duplicates table.
|
||||
while (@row = FetchSQLData()) {
|
||||
my $dupe_of = shift @row;
|
||||
my $dupe = shift @row;
|
||||
$dupes{$dupe} = $dupe_of;
|
||||
}
|
||||
|
||||
# Total up the number of bugs which are dupes of a given bug
|
||||
# count will then have key = "bug number",
|
||||
# value = "number of immediate dupes of that bug".
|
||||
foreach $key (keys(%dupes))
|
||||
{
|
||||
my $dupe_of = $dupes{$key};
|
||||
|
||||
if (!defined($count{$dupe_of})) {
|
||||
$count{$dupe_of} = 0;
|
||||
}
|
||||
|
||||
$count{$dupe_of}++;
|
||||
}
|
||||
|
||||
# Now we collapse the dupe tree by iterating over %count until
|
||||
# there is no further change.
|
||||
while ($changed == 1)
|
||||
{
|
||||
$changed = 0;
|
||||
foreach $key (keys(%count)) {
|
||||
# if this bug is actually itself a dupe, and has a count...
|
||||
if (defined($dupes{$key}) && $count{$key} > 0) {
|
||||
# add that count onto the bug it is a dupe of,
|
||||
# and zero the count; the check is to avoid
|
||||
# loops
|
||||
if ($count{$dupes{$key}} != 0) {
|
||||
$count{$dupes{$key}} += $count{$key};
|
||||
$count{$key} = 0;
|
||||
$changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Remove the values for which the count is zero
|
||||
foreach $key (keys(%count))
|
||||
{
|
||||
if ($count{$key} == 0) {
|
||||
delete $count{$key};
|
||||
}
|
||||
}
|
||||
|
||||
dbmclose(%count);
|
||||
}
|
||||
|
||||
sub today {
|
||||
my ($dom, $mon, $year) = (localtime(time))[3, 4, 5];
|
||||
return sprintf "%04d%02d%02d", 1900 + $year, ++$mon, $dom;
|
||||
}
|
||||
|
||||
sub today_dash {
|
||||
my ($dom, $mon, $year) = (localtime(time))[3, 4, 5];
|
||||
return sprintf "%04d-%02d-%02d", 1900 + $year, ++$mon, $dom;
|
||||
}
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html><head>
|
||||
|
||||
<!--
|
||||
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 Bugzilla Bug Tracking System.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape Communications
|
||||
Corporation. Portions created by Netscape are
|
||||
Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
-->
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>Understanding the UNCONFIRMED state, and other recent changes</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Understanding the UNCONFIRMED state, and other recent changes</h1>
|
||||
|
||||
<p>
|
||||
[This document is aimed primarily at people who have used Bugzilla
|
||||
before the UNCONFIRMED state was implemented. It might be helpful for
|
||||
newer users as well.]
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
New bugs in some products will now show up in a new state,
|
||||
UNCONFIRMED. This means that we have nobody has confirmed that the
|
||||
bug is real. Very busy engineers will probably generally ignore
|
||||
UNCONFIRMED that have been assigned to them, until they have been
|
||||
confirmed in one way or another. (Engineers with more time will
|
||||
hopefully glance over their UNCONFIRMED bugs regularly.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <a href="bug_status.html">page describing bug fields</a> has been
|
||||
updated to include UNCONFIRMED.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are two basic ways that a bug can become confirmed (and enter
|
||||
the NEW) state.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> A user with the appropriate permissions (see below for more on
|
||||
permissions) decides that the bug is a valid one, and confirms
|
||||
it. We hope to gather a small army of responsible volunteers
|
||||
to regularly go through bugs for us.</li>
|
||||
<li> The bug gathers a certain number of votes. <b>Any</b> valid Bugzilla user may vote for
|
||||
bugs (each user gets a certain number of bugs); any UNCONFIRMED bug which
|
||||
gets enough votes becomes automatically confirmed, and enters the NEW state.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
One implication of this is that it is worth your time to search the
|
||||
bug system for duplicates of your bug to vote on them, before
|
||||
submitting your own bug. If we can spread around knowledge of this
|
||||
fact, it ought to help cut down the number of duplicate bugs in the
|
||||
system.
|
||||
</p>
|
||||
|
||||
<h2>Permissions.</h2>
|
||||
|
||||
<p>
|
||||
Users now have a certain set of permissions. To see your permissions,
|
||||
check out the
|
||||
<a href="userprefs.cgi?bank=permissions">user preferences</a> page.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you have the "Can confirm a bug" permission, then you will be able
|
||||
to move UNCONFIRMED bugs into the NEW state.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you have the "Can edit all aspects of any bug" permission, then you
|
||||
can tweak anything about any bug. If not, you may only edit those
|
||||
bugs that you have submitted, or that you have assigned to you (or
|
||||
qa-assigned to you). However, anyone may add a comment to any bug.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Some people (initially, the initial owners and initial qa-contacts for
|
||||
components in the system) have the ability to give the above two
|
||||
permissions to other people. So, if you really feel that you ought to
|
||||
have one of these permissions, a good person to ask (via private
|
||||
email, please!) is the person who is assigned a relevant bug.
|
||||
</p>
|
||||
|
||||
<h2>Other details.</h2>
|
||||
|
||||
<p>
|
||||
An initial stab was taken to decide who would be given which of the
|
||||
above permissions. This was determined by some simple heurstics of
|
||||
who was assigned bugs, and who the default owners of bugs were, and a
|
||||
look at people who seem to have submitted several bugs that appear to
|
||||
have been interesting and valid. Inevitably, we have failed to give
|
||||
someone the permissions they deserve. Please don't take it
|
||||
personally; just bear with us as we shake out the new system.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
People with one of the two bits above can easily confirm their own
|
||||
bugs, so bugs they submit will actually start out in the NEW state.
|
||||
They can override this when submitting a bug.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
People can ACCEPT or RESOLVE a bug assigned to them, even if they
|
||||
aren't allowed to confirm it. However, the system remembers, and if
|
||||
the bug gets REOPENED or reassigned to someone else, it will revert
|
||||
back to the UNCONFIRMED state. If the bug has ever been confirmed,
|
||||
then REOPENing or reassigning will cause it to go to the NEW or
|
||||
REOPENED state.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that only some products support the UNCONFIRMED state. In other
|
||||
products, all new bugs will automatically start in the NEW state.
|
||||
</p>
|
||||
|
||||
<h2>Things still to be done.</h2>
|
||||
|
||||
<p>
|
||||
There probably ought to be a way to get a bug back into the
|
||||
UNCONFIRMED state, but there isn't yet.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a person has submitted several bugs that get confirmed, then this
|
||||
is probably a person who understands the system well, and deserves the
|
||||
"Can confirm a bug" permission. This kind of person should be
|
||||
detected and promoted automatically.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There should also be a way to automatically promote people to get the
|
||||
"Can edit all aspects of any bug" permission.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The "enter a new bug" page needs to be revamped with easy ways for new
|
||||
people to educate themselves on the benefit of searching for a bug
|
||||
like the one they're about to submit and voting on it, rather than
|
||||
adding a new useless duplicate.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
<!-- hhmts start -->
|
||||
Last modified: Sun Apr 14 12:55:14 EST 2002
|
||||
<!-- hhmts end -->
|
||||
</p>
|
||||
</body> </html>
|
||||
@@ -1,79 +0,0 @@
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
|
||||
# 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.
|
||||
#
|
||||
# This code is based on code found in bug_email.pl from the bugzilla
|
||||
# email tracker. Initial contributors are ::
|
||||
# Terry Weissman <terry@mozilla.org>
|
||||
# Gregor Fischer <fischer@suse.de>
|
||||
# Klaas Freitag <freitag@suse.de>
|
||||
# Seth Landsman <seth@dworkin.net>
|
||||
|
||||
# The purpose of this module is to abstract out a bunch of the code
|
||||
# that is central to email interfaces to bugzilla and its database
|
||||
|
||||
# Contributor : Seth Landsman <seth@dworkin.net>
|
||||
|
||||
# Initial checkin : 03/15/00 (SML)
|
||||
# findUser() function moved from bug_email.pl to here
|
||||
|
||||
push @INC, "../."; # this script now lives in contrib
|
||||
|
||||
require "globals.pl";
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
my $EMAIL_TRANSFORM_NONE = "email_transform_none";
|
||||
my $EMAIL_TRANSFORM_BASE_DOMAIN = "email_transform_base_domain";
|
||||
my $EMAIL_TRANSFORM_NAME_ONLY = "email_transform_name_only";
|
||||
|
||||
# change to do incoming email address fuzzy matching
|
||||
my $email_transform = $EMAIL_TRANSFORM_NAME_ONLY;
|
||||
|
||||
# findUser()
|
||||
# This function takes an email address and returns the user email.
|
||||
# matching is sloppy based on the $email_transform parameter
|
||||
sub findUser($) {
|
||||
my ($address) = @_;
|
||||
# if $email_transform is $EMAIL_TRANSFORM_NONE, return the address, otherwise, return undef
|
||||
if ($email_transform eq $EMAIL_TRANSFORM_NONE) {
|
||||
my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name = \'$address\';";
|
||||
SendSQL($stmt);
|
||||
my $found_address = FetchOneColumn();
|
||||
return $found_address;
|
||||
} elsif ($email_transform eq $EMAIL_TRANSFORM_BASE_DOMAIN) {
|
||||
my ($username) = ($address =~ /(.+)@/);
|
||||
my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';";
|
||||
SendSQL($stmt);
|
||||
|
||||
my $domain;
|
||||
my $found = undef;
|
||||
my $found_address;
|
||||
my $new_address = undef;
|
||||
while ((!$found) && ($found_address = FetchOneColumn())) {
|
||||
($domain) = ($found_address =~ /.+@(.+)/);
|
||||
if ($address =~ /$domain/) {
|
||||
$found = 1;
|
||||
$new_address = $found_address;
|
||||
}
|
||||
}
|
||||
return $new_address;
|
||||
} elsif ($email_transform eq $EMAIL_TRANSFORM_NAME_ONLY) {
|
||||
my ($username) = ($address =~ /(.+)@/);
|
||||
my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';";
|
||||
SendSQL($stmt);
|
||||
my $found_address = FetchOneColumn();
|
||||
return $found_address;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,22 +0,0 @@
|
||||
This directory contains contributed software related to Bugzilla.
|
||||
Things in here have not necessarily been tested or tried by anyone
|
||||
except the original contributor, so tred carefully. But it may still
|
||||
be useful to you.
|
||||
|
||||
This directory includes:
|
||||
|
||||
mysqld-watcher.pl -- This script can be installed as a frequent cron
|
||||
job to clean up stalled/dead queries.
|
||||
gnats2bz.pl -- A perl script to help import bugs from a GNATS
|
||||
database into a Bugzilla database. Contributed by
|
||||
Tom Schutter <tom@platte.com>
|
||||
|
||||
bug_email.pl -- A perl script that can receive email containing
|
||||
bug reports (email-interface). Contributed by
|
||||
Klaas Freitag <freitag@SuSE.de>
|
||||
|
||||
README.Mailif -- Readme describing the mail interface.
|
||||
bugmail_help.html -- User help page for the mail interface.
|
||||
|
||||
yp_nomail.sh -- Script you can run via cron that regularly updates
|
||||
the nomail file for terminated employees
|
||||
@@ -1,80 +0,0 @@
|
||||
|
||||
The Bugzilla Mail interface
|
||||
===========================
|
||||
|
||||
(UPDATE 03/14/00 to better reflect reality by SML)
|
||||
|
||||
The Bugzilla Mail interface allows to submit bugs to Bugzilla by email.
|
||||
|
||||
The Mail Interface Contribution consists of three files:
|
||||
README.Mailif - this readme.
|
||||
bug_email.pl - the script
|
||||
bugmail_help.html - a user help html site
|
||||
|
||||
Installation:
|
||||
|
||||
Next is to add a user who receives the bugmails, e. g. bugmail. Create a
|
||||
mail account and a home directory for the user.
|
||||
|
||||
The mailinterface script bug_email.pl needs to get the mail through stdin.
|
||||
I use procmail for that, with the following line in the .procmailrc:
|
||||
|
||||
BUGZILLA_HOME=/usr/local/httpd/htdocs/bugzilla
|
||||
:0 c
|
||||
|(cd $BUGZILLA_HOME/contrib; ./bug_email.pl)
|
||||
|
||||
This defines the Bugzilla directory as the variable BUGZILLA_HOME and passes
|
||||
all incoming mail to the script after cd'ing into the bugzilla home.
|
||||
|
||||
In some cases, it is necessary to alter the headers of incoming email. The
|
||||
additional line to procmail :
|
||||
|
||||
:0 fhw
|
||||
| formail -I "From " -a "From "
|
||||
|
||||
fixes many problems.
|
||||
|
||||
See bugzilla.procmailrc for a sample procmailrc that works for me (SML) and
|
||||
also deals with bugzilla_email_append.pl
|
||||
|
||||
Customation:
|
||||
|
||||
There are some values inside the script which need to be customized for your
|
||||
needs:
|
||||
|
||||
1. In sub-routine Reply (search 'sub Reply':
|
||||
there is the line
|
||||
print MAIL "From: Bugzilla Mailinterface<yourmail\@here.com>\n";
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
Fill in your correct mail here. That will make it easy for people to reply
|
||||
to the mail.
|
||||
|
||||
2. check, if your sendmail resides in /usr/sbin/sendmail, change the path if neccessary.
|
||||
Search the script after 'default' - you find some default-Settings for bug
|
||||
reports, which are used, if the sender did not send a field for it. The defaults
|
||||
should be checked and changed.
|
||||
|
||||
Thats hopefully all, we will come up with any configuration file or something.
|
||||
|
||||
|
||||
If your mail works, your script will insert mails from now on.
|
||||
|
||||
The mailinterface supports two commandline switches:
|
||||
|
||||
There are two command line switches :
|
||||
|
||||
-t: Testmode
|
||||
The mailinterface does not really insert the bug into the database, but
|
||||
writes some debug output to stdout and writes the mail into the file
|
||||
bug_email_test.log in the data-dir.
|
||||
|
||||
-r: restricted mode
|
||||
All lines before the first line with a keyword character are skipped.
|
||||
In not restricted, default mode, these lines are added to the long
|
||||
description of the bug.
|
||||
|
||||
|
||||
02/2000 - Klaas Freitag, SuSE GmbH <freitag@suse.de>
|
||||
03/2000 - Seth M. Landsman <seth@cs.brandeis.edu>
|
||||
bug_email.pl now lives out of bugzilla/contrib
|
||||
added line about formail
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,223 +0,0 @@
|
||||
<HTML>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<!--
|
||||
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 Bugzilla Bug Tracking System.
|
||||
|
||||
Contributor(s): Klaas Freitag <Freitag@SuSE.de>
|
||||
-->
|
||||
|
||||
<HEAD> <TITLE>Bugzilla Mail Interface</TITLE> </HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
<CENTER><H1>The Bugzilla Mail Interface</H1>
|
||||
Contributor: <A HREF="mailto:freitag@suse.de">Klaas Freitag</A>, SuSE GmbH
|
||||
</CENTER>
|
||||
<P>
|
||||
The bugzilla Mail interface allows the registered bugzilla users to submit bugs by
|
||||
sending email with a bug description. This is usefull for people, who do not work
|
||||
inhouse and want to submitt bugs to the bugzilla system.
|
||||
<p>
|
||||
|
||||
|
||||
I know, show me the <A HREF="#examplemail">example-mail !</A>
|
||||
|
||||
|
||||
<H2>What do you need to do to submitt a bug by mail ?</H2>
|
||||
You need to send a email in the described format to the bugmail-user of the
|
||||
bugzilla-system. This is <A HREF="mailto:our_bugzilla@xyz.com">yourbugzilla@here.com</A>
|
||||
|
||||
You receive a reply mail with the new bug-ID if your request was ok.
|
||||
If not, you get a mail with
|
||||
some help on the bugmail system and a specific analysis of your request.
|
||||
<P>
|
||||
Please dont refuse to send one or two wrong mails, you will get all the information
|
||||
you need in the replies, and <I>only</I> in the mail replies. The information on this
|
||||
page, concerning available products, versions and so on, is not dynamicly generated and
|
||||
may be old therefore.
|
||||
|
||||
<H1>The Mail Format</H1>
|
||||
The bugmail needs a special format , which consists of some keywords and suitable
|
||||
values for them and a description text. Note that the keyword block needs to be
|
||||
above of the description text.
|
||||
|
||||
<H2>Keywords</H2>
|
||||
You need to tell bugzilla some properties of the bugs. This is done by keywords, which
|
||||
start on a new line with a @, followed by the keyword and and equal-sign, followed by a
|
||||
hopefully valid value.
|
||||
|
||||
|
||||
<TABLE BORDER=4 FRAME=box CELLSPACING="5" width=95%> <COLGROUP> <col width="2*">
|
||||
<col width="5*"> <col width="1*"> </COLGROUP>
|
||||
<TR>
|
||||
<TH>Keyword</TH>
|
||||
<TH>Value description</TH>
|
||||
<TH>required and default value</TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@product</TD>
|
||||
<TD>The product which has a bug</TD>
|
||||
<TD>yes. <br> This is the most important information. Many other
|
||||
fields depend on the product.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@component</TD>
|
||||
<TD>the desired component which is affected by the bug</TD>
|
||||
<TD>yes. <br> As the @product, this is a very important
|
||||
field.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@version</TD>
|
||||
<TD>The version of the product</TD>
|
||||
<TD>yes. <br>See @product and @component</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@short_desc</TD>
|
||||
<TD>A summary of your bug report</TD>
|
||||
<TD>yes. <br>This summary of the error you want to report
|
||||
describes what happen. You may skip the long description,
|
||||
but not this summary.<br>
|
||||
<b>Note:</b>The short description may be given in the mail subject
|
||||
instead of using the keyword !</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@rep_platform</TD>
|
||||
<TD>The desired platform</TD>
|
||||
<TD>no.<br>If you dont give a value, this field is set to <I>All</I>.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@bug_severity</TD>
|
||||
<TD>The severity of the bug</TD>
|
||||
<TD>no. <br> If you dont give a value, this field is set to
|
||||
<I>normal</I></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@priority</TD>
|
||||
<TD>The priority of the bug</TD>
|
||||
<TD>no.<br>If you dont give a value, this field is set to <I>P3</I></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@op_sys</TD>
|
||||
<TD>The operating system</TD>
|
||||
<TD>no.<br>If you dont give a value, this field is set to <I>Linux</I>.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@assigned_to</TD>
|
||||
<TD>The one to whom the bug is assigned to</TD>
|
||||
<TD>no. <br>There is an initial owner for every product/version/component.
|
||||
He owns the bug by default. The initial owner can only be found if
|
||||
product, version and component are valid.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@bug_file_loc</TD>
|
||||
<TD>?</TD>
|
||||
<TD>no.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@status_whiteboard</TD>
|
||||
<TD>?</TD>
|
||||
<TD>no.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@target_milestone</TD>
|
||||
<TD>?</TD>
|
||||
<TD>no.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@groupset</TD>
|
||||
<TD>rules the visibility of the bug.</TD>
|
||||
<TD>no.<br>This value defaults to the smallest of the available groups,
|
||||
which is <I>readInternal</I>.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>@qa_contact</TD>
|
||||
<TD>the quality manager for the product</TD>
|
||||
<TD>no.<br>This value can be retrieved from product, component and
|
||||
version</TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<H2>Valid values</H2>
|
||||
Give string values for the most keys above. Some keywords require special values:<br>
|
||||
<ol>
|
||||
<li>E-Mail adresses: If you want to set the qa-contact, specify a email-adress for @qa_contact. The email must be known by bugzilla of course.</li>
|
||||
<li>Listvalues: Most of the values have to be one of a list of valid values. Try by sending
|
||||
a mail and read the reply. Skip fields if you dont get help for them unless you dont know
|
||||
which values you may choose.</li>
|
||||
<li>free Text: The descriptions may be free text. </li>
|
||||
<li>Special: The field groupset may be specified in different in three different kinds:
|
||||
<ol>
|
||||
<li> A plain numeric way, which is one usually huge number, e. g. <I>65536</I></li>
|
||||
<li> a string with added numbers e.g. <I>65536+131072</I></li>
|
||||
<li> a string list, e.g. <I>ReadInternal, ReadBeta </I></li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
|
||||
But most of them need <b>valid</b> values.
|
||||
<p>
|
||||
Sorry, you will not find lists of valid products, components and the other stuff
|
||||
here. Send a mail to with any text, and you will get a list of valid keywords in the reply.
|
||||
|
||||
<p>
|
||||
Some of the values must be choosen from a list:<br>
|
||||
<ol>
|
||||
<li>bug_severity: blocker, critical, major, normal, minor, trivial, enhancement</li>
|
||||
<li>op_sys: Linux </li>
|
||||
<li>priority: P1, P2, P3, P4, P5</li>
|
||||
<li>rep_platform: All, i386, AXP, i686, Other</li></ol>
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
After you have specified the required keywords and maybe some other value, you may
|
||||
describe your bug. You dont need a keyword for starting your bug description. All
|
||||
text which follows the keyword block is handled as long description of the bug.
|
||||
<p>
|
||||
|
||||
The bugmail interface is able to find required information by itself. E.g. if you specify
|
||||
a product which has exactly one component, this component will be found by the interface
|
||||
automatically.
|
||||
|
||||
<H1>Attachments</H1>
|
||||
|
||||
The mail interface is able to cope with MIME-attachments.
|
||||
People could for example add a logfile as a mail attachment, and it will appear in
|
||||
bugzilla as attachment. A comment for the attachment should be added, it will describe
|
||||
the attachment in bugzilla.
|
||||
|
||||
<H1><A NAME="examplemail">Example Mail</A></H1>
|
||||
|
||||
See the example of the mail <b>body</b> (Dont forget to specify the short description
|
||||
in the mail subject):<hr><pre>
|
||||
|
||||
@product = Bugzilla
|
||||
@component = general
|
||||
@version = All
|
||||
@groupset = ReadWorld ReadPartners
|
||||
@op_sys = Linux
|
||||
@priority = P3
|
||||
@rep_platform = i386
|
||||
|
||||
|
||||
This is the description of the bug I found. It is not neccessary to start
|
||||
it with a keyword.
|
||||
|
||||
Note: The short_description is neccessary and may be given with the keyword
|
||||
@short_description or will be retrieved from the mail subject.
|
||||
|
||||
|
||||
</pre><hr>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -1,30 +0,0 @@
|
||||
:0 fhw
|
||||
| formail -I "From " -a "From "
|
||||
|
||||
BUGZILLA_HOME=/home/bugzilla/WEB/bugzilla/contrib
|
||||
|
||||
:0
|
||||
* ^Subject: .*\[Bug .*\]
|
||||
RESULT=|(cd $BUGZILLA_HOME && ./bugzilla_email_append.pl)
|
||||
|
||||
|
||||
# Feed mail to stdin of bug_email.pl
|
||||
:0 Ec
|
||||
#* !^Subject: .*[Bug .*]
|
||||
RESULT=|(cd $BUGZILLA_HOME && ./bug_email.pl )
|
||||
|
||||
# write result to a logfile
|
||||
:0 c
|
||||
|echo `date '+%d.%m.%y %H:%M: '` $RESULT >> $HOME/bug_email.log
|
||||
|
||||
|
||||
:0 c
|
||||
|echo "----------------------------------" >> $HOME/bug_email.log
|
||||
|
||||
:0 c
|
||||
$HOME/bug_email.log
|
||||
|
||||
# Move mail to the inbox
|
||||
:0
|
||||
$HOME/Mail/INBOX
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
|
||||
# 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 purpose of this script is to take an email message, which
|
||||
# specifies a bugid and append it to the bug as part of the longdesc
|
||||
# table
|
||||
|
||||
# Contributor : Seth M. Landsman <seth@dworkin.net>
|
||||
|
||||
# 03/15/00 : Initial version by SML
|
||||
# 03/15/00 : processmail gets called
|
||||
|
||||
# Email subject must be of format :
|
||||
# .* Bug ### .*
|
||||
# replying to a typical bugzilla email should be valid
|
||||
|
||||
# TODO :
|
||||
# 1. better way to get the body text (I don't know what dump_entity() is
|
||||
# actually doing
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
use MIME::Parser;
|
||||
|
||||
push @INC, "../."; # this script lives in contrib
|
||||
require "globals.pl";
|
||||
require "BugzillaEmail.pm";
|
||||
|
||||
# Create a new MIME parser:
|
||||
my $parser = new MIME::Parser;
|
||||
|
||||
my $Comment = "";
|
||||
|
||||
# Create and set the output directory:
|
||||
# FIXME: There should be a $BUGZILLA_HOME variable (SML)
|
||||
(-d "../data/mimedump-tmp") or mkdir "../data/mimedump-tmp",0755 or die "mkdir: $!";
|
||||
(-w "../data/mimedump-tmp") or die "can't write to directory";
|
||||
|
||||
$parser->output_dir("../data/mimedump-tmp");
|
||||
|
||||
# Read the MIME message:
|
||||
my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream";
|
||||
$entity->remove_sig(10); # Removes the signature in the last 10 lines
|
||||
|
||||
# Getting values from parsed mail
|
||||
my $Sender = $entity->get( 'From' );
|
||||
$Sender ||= $entity->get( 'Reply-To' );
|
||||
my $Message_ID = $entity->get( 'Message-Id' );
|
||||
|
||||
die (" *** Cant find Sender-adress in sent mail ! ***\n" ) unless defined( $Sender );
|
||||
chomp( $Sender );
|
||||
chomp( $Message_ID );
|
||||
|
||||
print "Dealing with the sender $Sender\n";
|
||||
|
||||
ConnectToDatabase();
|
||||
|
||||
my $SenderShort = $Sender;
|
||||
$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/;
|
||||
|
||||
$SenderShort = findUser($SenderShort);
|
||||
|
||||
print "SenderShort is $SenderShort\n";
|
||||
if (!defined($SenderShort)) {
|
||||
$SenderShort = $Sender;
|
||||
$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/;
|
||||
}
|
||||
print "The sendershort is now $SenderShort\n";
|
||||
|
||||
if (!defined($SenderShort)) {
|
||||
DealWithError("No such user $SenderShort exists.");
|
||||
}
|
||||
|
||||
my $Subject = $entity->get('Subject');
|
||||
print "The subject is $Subject\n";
|
||||
|
||||
my ($bugid) = ($Subject =~ /\[Bug ([\d]+)\]/);
|
||||
print "The bugid is $bugid\n";
|
||||
|
||||
# make sure the bug exists
|
||||
|
||||
SendSQL("SELECT bug_id FROM bugs WHERE bug_id = $bugid;");
|
||||
my $found_id = FetchOneColumn();
|
||||
print "Did we find the bug? $found_id-\n";
|
||||
if (!defined($found_id)) {
|
||||
DealWithError("Bug $bugid does not exist");
|
||||
}
|
||||
|
||||
# get the user id
|
||||
SendSQL("SELECT userid FROM profiles WHERE login_name = \'$SenderShort\';");
|
||||
my $userid = FetchOneColumn();
|
||||
if (!defined($userid)) {
|
||||
DealWithError("Userid not found for $SenderShort");
|
||||
}
|
||||
|
||||
# parse out the text of the message
|
||||
dump_entity($entity);
|
||||
|
||||
# Get rid of the bug id
|
||||
$Subject =~ s/\[Bug [\d]+\]//;
|
||||
#my $Comment = "This is only a test ...";
|
||||
my $Body = "Subject: " . $Subject . "\n" . $Comment;
|
||||
|
||||
# shove it in the table
|
||||
my $long_desc_query = "INSERT INTO longdescs SET bug_id=$found_id, who=$userid, bug_when=NOW(), thetext=" . SqlQuote($Body) . ";";
|
||||
SendSQL($long_desc_query);
|
||||
|
||||
system("cd .. ; ./processmail $found_id '$SenderShort'");
|
||||
|
||||
sub DealWithError {
|
||||
my ($reason) = @_;
|
||||
print $reason . "\n";
|
||||
}
|
||||
|
||||
# Yanking this wholesale from bug_email, 'cause I know this works. I'll
|
||||
# figure out what it really does later
|
||||
#------------------------------
|
||||
#
|
||||
# dump_entity ENTITY, NAME
|
||||
#
|
||||
# Recursive routine for parsing a mime coded mail.
|
||||
# One mail may contain more than one mime blocks, which need to be
|
||||
# handled. Therefore, this function is called recursively.
|
||||
#
|
||||
# It gets the for bugzilla important information from the mailbody and
|
||||
# stores them into the global attachment-list @attachments. The attachment-list
|
||||
# is needed in storeAttachments.
|
||||
#
|
||||
sub dump_entity {
|
||||
my ($entity, $name) = @_;
|
||||
defined($name) or $name = "'anonymous'";
|
||||
my $IO;
|
||||
|
||||
|
||||
# Output the body:
|
||||
my @parts = $entity->parts;
|
||||
if (@parts) { # multipart...
|
||||
my $i;
|
||||
foreach $i (0 .. $#parts) { # dump each part...
|
||||
dump_entity($parts[$i], ("$name, part ".(1+$i)));
|
||||
}
|
||||
} else { # single part...
|
||||
|
||||
# Get MIME type, and display accordingly...
|
||||
my $msg_part = $entity->head->get( 'Content-Disposition' );
|
||||
|
||||
$msg_part ||= "";
|
||||
|
||||
my ($type, $subtype) = split('/', $entity->head->mime_type);
|
||||
my $body = $entity->bodyhandle;
|
||||
my ($data, $on_disk );
|
||||
|
||||
if( $msg_part =~ /^attachment/ ) {
|
||||
# Attached File
|
||||
my $des = $entity->head->get('Content-Description');
|
||||
$des ||= "";
|
||||
|
||||
if( defined( $body->path )) { # Data is on disk
|
||||
$on_disk = 1;
|
||||
$data = $body->path;
|
||||
|
||||
} else { # Data is in core
|
||||
$on_disk = 0;
|
||||
$data = $body->as_string;
|
||||
}
|
||||
# push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] );
|
||||
} else {
|
||||
# Real Message
|
||||
if ($type =~ /^(text|message)$/) { # text: display it...
|
||||
if ($IO = $body->open("r")) {
|
||||
$Comment .= $_ while (defined($_ = $IO->getline));
|
||||
$IO->close;
|
||||
} else { # d'oh!
|
||||
print "$0: couldn't find/open '$name': $!";
|
||||
}
|
||||
} else { print "Oooops - no Body !\n"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
#!/bin/sh
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Andreas Franke <afranke@ags.uni-sb.de>.
|
||||
# Corporation. Portions created by Andreas Franke are
|
||||
# Copyright (C) 2001 Andreas Franke. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
conf="`dirname $0`/query.conf"
|
||||
|
||||
query="http://bugzilla.mozilla.org/buglist.cgi?cmd=doit"
|
||||
defaultcolumnlist="severity priority platform status resolution target_milestone status_whiteboard keywords summaryfull"
|
||||
|
||||
chart=0
|
||||
and=0
|
||||
while test "$1" != ""; do
|
||||
arg=$1
|
||||
arg_len=`expr length ${arg}`
|
||||
if test `expr substr "${arg}" 1 2` == "--"; then
|
||||
eq_pos=`expr match ${arg} '--.*='`
|
||||
if test "${eq_pos}" == "0"; then
|
||||
echo 'Missing value for long option '"${arg}"' ("=" not found)' 1>&2
|
||||
exit 1;
|
||||
fi
|
||||
# extract option name
|
||||
let name_len=${eq_pos}-3
|
||||
name=`expr substr ${arg} 3 ${name_len}`
|
||||
# extract option value
|
||||
let val_start=${eq_pos}+1
|
||||
let val_len=${arg_len}-${eq_pos}
|
||||
val=`expr substr ${arg} ${val_start} ${val_len}`
|
||||
elif test `expr substr ${arg} 1 1` == "-" &&
|
||||
test "`expr substr ${arg} 2 1`" != ""; then
|
||||
# extract
|
||||
name=`expr substr ${arg} 2 1`
|
||||
let val_len=${arg_len}-2
|
||||
val=`expr substr ${arg} 3 ${val_len}`
|
||||
else
|
||||
name="default"
|
||||
val="${arg}"
|
||||
#echo "Unrecognized option ${arg}" 1>&2
|
||||
#exit 1
|
||||
fi
|
||||
|
||||
# find field and comparison type for option ${name}
|
||||
field=`grep '"'${name}'"' ${conf} | awk '{printf $1}'`
|
||||
type=`grep '"'${name}'"' ${conf} | awk '{printf $2}'`
|
||||
if test "${field}" == "" || test "${type}" == ""; then
|
||||
echo "Field name & comparison type not found for option ${name}." 1>&2
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
or=0
|
||||
while test "${val}" != ""; do
|
||||
comma_idx=`expr index ${val} ,`
|
||||
if test ${comma_idx} == "0"; then
|
||||
val1="${val}"
|
||||
val=""
|
||||
else
|
||||
let val1_len=${comma_idx}-1
|
||||
val1=`expr substr ${val} 1 ${val1_len}`
|
||||
val_len=`expr length ${val}`
|
||||
let rest_start=${comma_idx}+1
|
||||
let rest_len=${val_len}-${comma_idx}
|
||||
val=`expr substr ${val} ${rest_start} ${rest_len}`
|
||||
fi
|
||||
query="${query}&field${chart}-${and}-${or}=${field}"
|
||||
query="${query}&type${chart}-${and}-${or}=${type}"
|
||||
query="${query}&value${chart}-${and}-${or}=${val1}"
|
||||
#echo "----- ${name} : ${field} : ${type} : ${val1} -----" 1>&2
|
||||
let or=${or}+1
|
||||
done
|
||||
let chart=${chart}+1
|
||||
shift
|
||||
done
|
||||
|
||||
outputfile="/dev/stdout"
|
||||
#outputfile="buglist.html"
|
||||
#\rm -f ${outputfile}
|
||||
wget -q -O ${outputfile} --header="Cookie: COLUMNLIST=${COLUMNLIST-${defaultcolumnlist}}" "${query}"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Andreas Franke <afranke@ags.uni-sb.de>.
|
||||
# Corporation. Portions created by Andreas Franke are
|
||||
# Copyright (C) 2001 Andreas Franke. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
buglist="`dirname $0`/buglist"
|
||||
htmlfile="`dirname $0`/buglist.html"
|
||||
|
||||
${buglist} "$@" 2>&1 1>${htmlfile}
|
||||
if test ${?} == "0"; then
|
||||
echo `grep 'TR VALIGN=TOP ALIGN=LEFT CLASS=' ${htmlfile} | sed -e 's/<TR.*id=//' | sed -e 's/".*//'` | sed -e 's/ /\,/g'
|
||||
else
|
||||
cat ${htmlfile} 1>&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,49 +0,0 @@
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Andreas Franke <afranke@ags.uni-sb.de>.
|
||||
# Corporation. Portions created by Andreas Franke are
|
||||
# Copyright (C) 2001 Andreas Franke. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
#
|
||||
# This is `query.conf', the config file for `buglist'.
|
||||
#
|
||||
# Columns: 1: field_name, 2: comparison_type, 3: cmd-line options
|
||||
#
|
||||
bug_status substring "s","status"
|
||||
resolution substring "r","resolution"
|
||||
rep_platform substring "p","platform"
|
||||
op_sys substring "o","os","opsys"
|
||||
priority substring "p","priority"
|
||||
bug_severity substring "S","severity"
|
||||
assigned_to substring "A","O","owner","assignedto"
|
||||
reporter substring "R","reporter"
|
||||
qa_contact substring "Q","qa","qacontact"
|
||||
cc substring "C","cc"
|
||||
product substring "product"
|
||||
version substring "V","version"
|
||||
component substring "c","component"
|
||||
target_milestone substring "M","milestone"
|
||||
short_desc substring "default","summary"
|
||||
longdesc substring "d","description","longdesc"
|
||||
bug_file_loc substring "u","url"
|
||||
status_whiteboard substring "w","whiteboard"
|
||||
keywords substring "k","K","keywords"
|
||||
attachments.description substring "attachdesc"
|
||||
attachments.thedata substring "attachdata"
|
||||
attachments.mimetype substring "attachmime"
|
||||
dependson substring # bug 30823
|
||||
blocked substring # bug 30823
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Dawn Endico <endico@mozilla.org>
|
||||
|
||||
|
||||
# Keep a record of all cvs updates made from a given directory.
|
||||
#
|
||||
# Later, if changes need to be backed out, look at the log file
|
||||
# and run the cvs command with the date that you want to back
|
||||
# out to. (Probably the second to last entry).
|
||||
|
||||
#DATE=`date +%e/%m/%Y\ %k:%M:%S\ %Z`
|
||||
DATE=`date`
|
||||
COMMAND="cvs update -d -P -D"
|
||||
echo $COMMAND \"$DATE\" >> cvs-update.log
|
||||
$COMMAND "$DATE"
|
||||
|
||||
|
||||
# sample log file
|
||||
#cvs update -P -D "11/04/2000 20:22:08 PDT"
|
||||
#cvs update -P -D "11/05/2000 20:22:22 PDT"
|
||||
#cvs update -P -D "11/07/2000 20:26:29 PDT"
|
||||
#cvs update -P -D "11/08/2000 20:27:10 PDT"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,303 +0,0 @@
|
||||
#!/usr/local/bin/python
|
||||
# -*- mode: python -*-
|
||||
|
||||
"""
|
||||
jb2bz.py - a nonce script to import bugs from JitterBug to Bugzilla
|
||||
Written by Tom Emerson, tree@basistech.com
|
||||
|
||||
This script is provided in the hopes that it will be useful. No
|
||||
rights reserved. No guarantees expressed or implied. Use at your own
|
||||
risk. May be dangerous if swallowed. If it doesn't work for you, don't
|
||||
blame me. It did what I needed it to do.
|
||||
|
||||
This code requires a recent version of Andy Dustman's MySQLdb interface,
|
||||
|
||||
http://sourceforge.net/projects/mysql-python
|
||||
|
||||
Share and enjoy.
|
||||
"""
|
||||
|
||||
import rfc822, mimetools, multifile, mimetypes
|
||||
import sys, re, glob, StringIO, os, stat, time
|
||||
import MySQLdb, getopt
|
||||
|
||||
# mimetypes doesn't include everything we might encounter, yet.
|
||||
if not mimetypes.types_map.has_key('.doc'):
|
||||
mimetypes.types_map['.doc'] = 'application/msword'
|
||||
|
||||
if not mimetypes.encodings_map.has_key('.bz2'):
|
||||
mimetypes.encodings_map['.bz2'] = "bzip2"
|
||||
|
||||
bug_status='NEW'
|
||||
component="default"
|
||||
version=""
|
||||
product="" # this is required, the rest of these are defaulted as above
|
||||
|
||||
"""
|
||||
Each bug in JitterBug is stored as a text file named by the bug number.
|
||||
Additions to the bug are indicated by suffixes to this:
|
||||
|
||||
<bug>
|
||||
<bug>.followup.*
|
||||
<bug>.reply.*
|
||||
<bug>.notes
|
||||
|
||||
The dates on the files represent the respective dates they were created/added.
|
||||
|
||||
All <bug>s and <bug>.reply.*s include RFC 822 mail headers. These could include
|
||||
MIME file attachments as well that would need to be extracted.
|
||||
|
||||
There are other additions to the file names, such as
|
||||
|
||||
<bug>.notify
|
||||
|
||||
which are ignored.
|
||||
|
||||
Bugs in JitterBug are organized into directories. At Basis we used the following
|
||||
naming conventions:
|
||||
|
||||
<product>-bugs Open bugs
|
||||
<product>-requests Open Feature Requests
|
||||
<product>-resolved Bugs/Features marked fixed by engineering, but not verified
|
||||
<product>-verified Resolved defects that have been verified by QA
|
||||
|
||||
where <product> is either:
|
||||
|
||||
<product-name>
|
||||
|
||||
or
|
||||
|
||||
<product-name>-<version>
|
||||
"""
|
||||
|
||||
def process_notes_file(current, fname):
|
||||
try:
|
||||
new_note = {}
|
||||
notes = open(fname, "r")
|
||||
s = os.fstat(notes.fileno())
|
||||
|
||||
new_note['text'] = notes.read()
|
||||
new_note['timestamp'] = time.gmtime(s[stat.ST_MTIME])
|
||||
|
||||
notes.close()
|
||||
|
||||
current['notes'].append(new_note)
|
||||
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
def process_reply_file(current, fname):
|
||||
new_note = {}
|
||||
reply = open(fname, "r")
|
||||
msg = rfc822.Message(reply)
|
||||
new_note['text'] = "%s\n%s" % (msg['From'], msg.fp.read())
|
||||
new_note['timestamp'] = rfc822.parsedate_tz(msg['Date'])
|
||||
current["notes"].append(new_note)
|
||||
|
||||
def add_notes(current):
|
||||
"""Add any notes that have been recorded for the current bug."""
|
||||
process_notes_file(current, "%d.notes" % current['number'])
|
||||
|
||||
for f in glob.glob("%d.reply.*" % current['number']):
|
||||
process_reply_file(current, f)
|
||||
|
||||
for f in glob.glob("%d.followup.*" % current['number']):
|
||||
process_reply_file(current, f)
|
||||
|
||||
def maybe_add_attachment(current, file, submsg):
|
||||
"""Adds the attachment to the current record"""
|
||||
cd = submsg["Content-Disposition"]
|
||||
m = re.search(r'filename="([^"]+)"', cd)
|
||||
if m == None:
|
||||
return
|
||||
attachment_filename = m.group(1)
|
||||
if (submsg.gettype() == 'application/octet-stream'):
|
||||
# try get a more specific content-type for this attachment
|
||||
type, encoding = mimetypes.guess_type(m.group(1))
|
||||
if type == None:
|
||||
type = submsg.gettype()
|
||||
else:
|
||||
type = submsg.gettype()
|
||||
|
||||
try:
|
||||
data = StringIO.StringIO()
|
||||
mimetools.decode(file, data, submsg.getencoding())
|
||||
except:
|
||||
return
|
||||
|
||||
current['attachments'].append( ( attachment_filename, type, data.getvalue() ) )
|
||||
|
||||
def process_mime_body(current, file, submsg):
|
||||
data = StringIO.StringIO()
|
||||
mimetools.decode(file, data, submsg.getencoding())
|
||||
current['description'] = data.getvalue()
|
||||
|
||||
|
||||
|
||||
def process_text_plain(msg, current):
|
||||
print "Processing: %d" % current['number']
|
||||
current['description'] = msg.fp.read()
|
||||
|
||||
def process_multi_part(file, msg, current):
|
||||
print "Processing: %d" % current['number']
|
||||
mf = multifile.MultiFile(file)
|
||||
mf.push(msg.getparam("boundary"))
|
||||
while mf.next():
|
||||
submsg = mimetools.Message(file)
|
||||
if submsg.has_key("Content-Disposition"):
|
||||
maybe_add_attachment(current, mf, submsg)
|
||||
else:
|
||||
# This is the message body itself (always?), so process
|
||||
# accordingly
|
||||
process_mime_body(current, mf, submsg)
|
||||
|
||||
def process_jitterbug(filename):
|
||||
current = {}
|
||||
current['number'] = int(filename)
|
||||
current['notes'] = []
|
||||
current['attachments'] = []
|
||||
current['description'] = ''
|
||||
current['date-reported'] = ()
|
||||
current['short-description'] = ''
|
||||
|
||||
file = open(filename, "r")
|
||||
msg = mimetools.Message(file)
|
||||
|
||||
msgtype = msg.gettype()
|
||||
|
||||
add_notes(current)
|
||||
current['date-reported'] = rfc822.parsedate_tz(msg['Date'])
|
||||
current['short-description'] = msg['Subject']
|
||||
|
||||
if msgtype[:5] == 'text/':
|
||||
process_text_plain(msg, current)
|
||||
elif msgtype[:10] == "multipart/":
|
||||
process_multi_part(file, msg, current)
|
||||
else:
|
||||
# Huh? This should never happen.
|
||||
print "Unknown content-type: %s" % msgtype
|
||||
sys.exit(1)
|
||||
|
||||
# At this point we have processed the message: we have all of the notes and
|
||||
# attachments stored, so it's time to add things to the database.
|
||||
# The schema for JitterBug 2.14 can be found at:
|
||||
#
|
||||
# http://www.trilobyte.net/barnsons/html/dbschema.html
|
||||
#
|
||||
# The following fields need to be provided by the user:
|
||||
#
|
||||
# bug_status
|
||||
# product
|
||||
# version
|
||||
# reporter
|
||||
# component
|
||||
# resolution
|
||||
|
||||
# change this to the user_id of the Bugzilla user who is blessed with the
|
||||
# imported defects
|
||||
reporter=6
|
||||
|
||||
# the resolution will need to be set manually
|
||||
resolution=""
|
||||
|
||||
db = MySQLdb.connect(db='bugs',user='root',host='localhost')
|
||||
cursor = db.cursor()
|
||||
|
||||
cursor.execute( "INSERT INTO bugs SET " \
|
||||
"bug_id=%s," \
|
||||
"bug_severity='normal'," \
|
||||
"bug_status=%s," \
|
||||
"creation_ts=%s," \
|
||||
"short_desc=%s," \
|
||||
"product=%s," \
|
||||
"rep_platform='All'," \
|
||||
"assigned_to=%s,"
|
||||
"reporter=%s," \
|
||||
"version=%s," \
|
||||
"component=%s," \
|
||||
"resolution=%s",
|
||||
[ current['number'],
|
||||
bug_status,
|
||||
time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
|
||||
current['short-description'],
|
||||
product,
|
||||
reporter,
|
||||
reporter,
|
||||
version,
|
||||
component,
|
||||
resolution] )
|
||||
|
||||
# This is the initial long description associated with the bug report
|
||||
cursor.execute( "INSERT INTO longdescs VALUES (%s,%s,%s,%s)",
|
||||
[ current['number'],
|
||||
reporter,
|
||||
time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
|
||||
current['description'] ] )
|
||||
|
||||
# Add whatever notes are associated with this defect
|
||||
for n in current['notes']:
|
||||
cursor.execute( "INSERT INTO longdescs VALUES (%s,%s,%s,%s)",
|
||||
[current['number'],
|
||||
reporter,
|
||||
time.strftime("%Y-%m-%d %H:%M:%S", n['timestamp'][:9]),
|
||||
n['text']])
|
||||
|
||||
# add attachments associated with this defect
|
||||
for a in current['attachments']:
|
||||
cursor.execute( "INSERT INTO attachments SET " \
|
||||
"bug_id=%s, creation_ts=%s, description='', mimetype=%s," \
|
||||
"filename=%s, thedata=%s, submitter_id=%s",
|
||||
[ current['number'],
|
||||
time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
|
||||
a[1], a[0], a[2], reporter ])
|
||||
|
||||
cursor.close()
|
||||
db.close()
|
||||
|
||||
def usage():
|
||||
print """Usage: jb2bz.py [OPTIONS] Product
|
||||
|
||||
Where OPTIONS are one or more of the following:
|
||||
|
||||
-h This help information.
|
||||
-s STATUS One of UNCONFIRMED, NEW, ASSIGNED, REOPENED, RESOLVED, VERIFIED, CLOSED
|
||||
(default is NEW)
|
||||
-c COMPONENT The component to attach to each bug as it is important. This should be
|
||||
valid component for the Product.
|
||||
-v VERSION Version to assign to these defects.
|
||||
|
||||
Product is the Product to assign these defects to.
|
||||
|
||||
All of the JitterBugs in the current directory are imported, including replies, notes,
|
||||
attachments, and similar noise.
|
||||
"""
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
global bug_status, component, version, product
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hs:c:v:")
|
||||
|
||||
for o,a in opts:
|
||||
if o == "-s":
|
||||
if a in ('UNCONFIRMED','NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED'):
|
||||
bug_status = a
|
||||
elif o == '-c':
|
||||
component = a
|
||||
elif o == '-v':
|
||||
version = a
|
||||
elif o == '-h':
|
||||
usage()
|
||||
|
||||
if len(args) != 1:
|
||||
sys.stderr.write("Must specify the Product.\n")
|
||||
sys.exit(1)
|
||||
|
||||
product = args[0]
|
||||
|
||||
for bug in filter(lambda x: re.match(r"\d+$", x), glob.glob("*")):
|
||||
process_jitterbug(bug)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,102 +0,0 @@
|
||||
#!/usr/bonsaitools/bin/perl -w
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Dan Mosedale <dmose@mozilla.org>
|
||||
#
|
||||
|
||||
# mysqld-watcher.pl - a script that watches the running instance of
|
||||
# mysqld and kills off any long-running SELECTs against the shadow_db
|
||||
#
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
require "globals.pl";
|
||||
|
||||
# some configurables:
|
||||
|
||||
# length of time before a thread is eligible to be killed, in seconds
|
||||
#
|
||||
my $long_query_time = 600;
|
||||
#
|
||||
# the From header for any messages sent out
|
||||
#
|
||||
my $mail_from = "root\@lounge.mozilla.org";
|
||||
#
|
||||
# mail transfer agent. this should probably really be converted to a Param().
|
||||
#
|
||||
my $mta_program = "/usr/lib/sendmail -t -ODeliveryMode=deferred";
|
||||
|
||||
# and STDIN is where we get the info about running threads
|
||||
#
|
||||
close(STDIN);
|
||||
open(STDIN, "/usr/bonsaitools/bin/mysqladmin processlist |");
|
||||
|
||||
# iterate through the running threads
|
||||
#
|
||||
my @LONGEST = (0,0,0,0,0,0,0,0,0);
|
||||
while ( <STDIN> ) {
|
||||
my @F = split(/\|/);
|
||||
|
||||
# if this line is not the correct number of fields, or if the thread-id
|
||||
# field contains Id, skip this line. both these cases indicate that this
|
||||
# line contains pretty-printing gunk and not thread info.
|
||||
#
|
||||
next if ( $#F != 9 || $F[1] =~ /Id/);
|
||||
|
||||
if ( $F[4] =~ /shadow_bugs/ # shadowbugs database in use
|
||||
&& $F[5] =~ /Query/ # this is actually a query
|
||||
&& $F[6] > $long_query_time # this query has taken too long
|
||||
&& $F[8] =~ /(select|SELECT)/ # only kill a select
|
||||
&& $F[6] > $LONGEST[6] ) { # the longest running query seen
|
||||
@LONGEST = @F;
|
||||
}
|
||||
}
|
||||
|
||||
# send an email message
|
||||
#
|
||||
# should perhaps be moved to somewhere more global for use in bugzilla as a
|
||||
# whole; should also do more error-checking
|
||||
#
|
||||
sub sendEmail($$$$) {
|
||||
($#_ == 3) || die("sendEmail: invalid number of arguments");
|
||||
my ($from, $to, $subject, $body) = @_;
|
||||
|
||||
open(MTA, "|$mta_program");
|
||||
print MTA "From: $from\n";
|
||||
print MTA "To: $to\n";
|
||||
print MTA "Subject: $subject\n";
|
||||
print MTA "\n";
|
||||
print MTA $body;
|
||||
print MTA "\n";
|
||||
close(MTA);
|
||||
|
||||
}
|
||||
|
||||
# if we found anything, kill the database thread and send mail about it
|
||||
#
|
||||
if ($LONGEST[6] != 0) {
|
||||
|
||||
system ("/usr/bonsaitools/bin/mysqladmin", "kill", $LONGEST[1]);
|
||||
|
||||
# fire off an email telling the maintainer that we had to kill a thread
|
||||
#
|
||||
sendEmail($mail_from, Param("maintainer"),
|
||||
"long running MySQL thread killed",
|
||||
join(" ", @LONGEST) . "\n");
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/sh
|
||||
# -*- Mode: ksh -*-
|
||||
##############################################################################
|
||||
# $Id: yp_nomail.sh,v 1.1 2000-09-12 23:50:31 cyeh%bluemartini.com Exp $
|
||||
# yp_nomail
|
||||
#
|
||||
# Our mail admins got annoyed when bugzilla kept sending email
|
||||
# to people who'd had bugzilla entries and left the company. They
|
||||
# were no longer in the list of valid email users so it'd bounce.
|
||||
# Maintaining the 'data/nomail' file was a pain. Luckily, our UNIX
|
||||
# admins list all the users that ever were, but the people who've left
|
||||
# have a distinct marker in their password file. For example:
|
||||
#
|
||||
# fired:*LK*:2053:1010:You're Fired Dude:/home/loser:/bin/false
|
||||
#
|
||||
# This script takes advantage of the "*LK*" convention seen via
|
||||
# ypcat passwd and dumps those people into the nomail file. Any
|
||||
# manual additions are kept in a "nomail.(domainname)" file and
|
||||
# appended to the list of yp lockouts every night via Cron
|
||||
#
|
||||
# 58 23 * * * /export/bugzilla/contrib/yp_nomail.sh > /dev/null 2>&1
|
||||
#
|
||||
# Tak ( Mark Takacs ) 08/2000
|
||||
#
|
||||
# XXX: Maybe should crosscheck w/bugzilla users?
|
||||
##############################################################################
|
||||
|
||||
####
|
||||
# Configure this section to suite yer installation
|
||||
####
|
||||
|
||||
DOMAIN=`domainname`
|
||||
MOZILLA_HOME="/export/mozilla"
|
||||
BUGZILLA_HOME="${MOZILLA_HOME}/bugzilla"
|
||||
NOMAIL_DIR="${BUGZILLA_HOME}/data"
|
||||
NOMAIL="${NOMAIL_DIR}/nomail"
|
||||
NOMAIL_ETIME="${NOMAIL}.${DOMAIN}"
|
||||
NOMAIL_YP="${NOMAIL}.yp"
|
||||
FIRED_FLAG="\*LK\*"
|
||||
|
||||
YPCAT="/usr/bin/ypcat"
|
||||
GREP="/usr/bin/grep"
|
||||
SORT="/usr/bin/sort"
|
||||
|
||||
########################## no more config needed #################
|
||||
|
||||
# This dir comes w/Bugzilla. WAY too paranoid
|
||||
if [ ! -d ${NOMAIL_DIR} ] ; then
|
||||
echo "Creating $date_dir"
|
||||
mkdir -p ${NOMAIL_DIR}
|
||||
fi
|
||||
|
||||
#
|
||||
# Do some (more) paranoid checking
|
||||
#
|
||||
touch ${NOMAIL}
|
||||
if [ ! -w ${NOMAIL} ] ; then
|
||||
echo "Can't write nomail file: ${NOMAIL} -- exiting"
|
||||
exit
|
||||
fi
|
||||
if [ ! -r ${NOMAIL_ETIME} ] ; then
|
||||
echo "Can't access custom nomail file: ${NOMAIL_ETIME} -- skipping"
|
||||
NOMAIL_ETIME=""
|
||||
fi
|
||||
|
||||
#
|
||||
# add all the people with '*LK*' password to the nomail list
|
||||
# XXX: maybe I should customize the *LK* string. Doh.
|
||||
#
|
||||
|
||||
LOCKOUT=`$YPCAT passwd | $GREP "${FIRED_FLAG}" | cut -d: -f1 | sort > ${NOMAIL_YP}`
|
||||
`cat ${NOMAIL_YP} ${NOMAIL_ETIME} > ${NOMAIL}`
|
||||
|
||||
exit
|
||||
|
||||
|
||||
# end
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/usr/bonsaitools/bin/perl -wT
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# 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 Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
# David Gardiner <david.gardiner@unisa.edu.au>
|
||||
# Joe Robins <jmrobins@tgix.com>
|
||||
# Christopher Aillon <christopher@aillon.com>
|
||||
# Gervase Markham <gerv@gerv.net>
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
use lib qw(.);
|
||||
|
||||
require "CGI.pl";
|
||||
require "globals.pl";
|
||||
|
||||
# Shut up misguided -w warnings about "used only once":
|
||||
use vars qw(
|
||||
%FORM
|
||||
$template
|
||||
$vars
|
||||
);
|
||||
|
||||
ConnectToDatabase();
|
||||
|
||||
# If we're using LDAP for login, then we can't create a new account here.
|
||||
if(Param('useLDAP')) {
|
||||
DisplayError("This site is using LDAP for authentication. Please contact
|
||||
an LDAP administrator to get a new account created.",
|
||||
"Can't create LDAP accounts");
|
||||
PutFooter();
|
||||
exit;
|
||||
}
|
||||
|
||||
# Clear out the login cookies. Make people log in again if they create an
|
||||
# account; otherwise, they'll probably get confused.
|
||||
my $cookiepath = Param("cookiepath");
|
||||
print "Set-Cookie: Bugzilla_login= ; path=$cookiepath; expires=Sun, 30-Jun-80 00:00:00 GMT
|
||||
Set-Cookie: Bugzilla_logincookie= ; path=$cookiepath; expires=Sun, 30-Jun-80 00:00:00 GMT\n";
|
||||
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
my $login = $::FORM{'login'};
|
||||
my $realname = trim($::FORM{'realname'});
|
||||
|
||||
if (defined($login)) {
|
||||
# We've been asked to create an account.
|
||||
CheckEmailSyntax($login);
|
||||
trick_taint($login);
|
||||
$vars->{'login'} = $login;
|
||||
|
||||
if (!ValidateNewUser($login)) {
|
||||
# Account already exists
|
||||
$template->process("account/exists.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
exit;
|
||||
}
|
||||
|
||||
# Create account
|
||||
my $password = InsertNewUser($login, $realname);
|
||||
MailPassword($login, $password);
|
||||
|
||||
$template->process("account/created.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
exit;
|
||||
}
|
||||
|
||||
# Show the standard "would you like to create an account?" form.
|
||||
$template->process("account/create.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user