Mercurial > projects > dwt-addons
comparison dwtx/draw2d/ImageUtilities.d @ 98:95307ad235d9
Added Draw2d code, still work in progress
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 03 Aug 2008 00:52:14 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
96:b492ba44e44d | 98:95307ad235d9 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2003, 2005 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.draw2d.ImageUtilities; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 | |
17 | |
18 static import dwt.graphics.Rectangle; | |
19 import dwt.DWT; | |
20 import dwt.graphics.Color; | |
21 import dwt.graphics.Font; | |
22 import dwt.graphics.FontMetrics; | |
23 import dwt.graphics.GC; | |
24 import dwt.graphics.Image; | |
25 import dwt.graphics.ImageData; | |
26 import dwt.graphics.PaletteData; | |
27 import dwt.graphics.RGB; | |
28 import dwt.widgets.Display; | |
29 import dwtx.draw2d.geometry.Dimension; | |
30 import dwtx.draw2d.FigureUtilities; | |
31 | |
32 /** | |
33 * @author Pratik Shah | |
34 * @since 3.0 | |
35 */ | |
36 public class ImageUtilities { | |
37 | |
38 /** | |
39 * Returns a new Image with the given String rotated left (by 90 degrees). The String | |
40 * will be rendered using the provided colors and fonts. The client is responsible for | |
41 * disposing the returned Image. Strings cannot contain newline or tab characters. This | |
42 * method MUST be invoked from the user-interface (Display) thread. | |
43 * | |
44 * @param string the String to be rendered | |
45 * @param font the font | |
46 * @param foreground the text's color | |
47 * @param background the background color | |
48 * @return an Image which must be disposed | |
49 */ | |
50 public static Image createRotatedImageOfString(String string, Font font, | |
51 Color foreground, Color background) { | |
52 Display display = Display.getCurrent(); | |
53 if (display is null) | |
54 DWT.error(DWT.ERROR_THREAD_INVALID_ACCESS); | |
55 | |
56 FontMetrics metrics = FigureUtilities.getFontMetrics(font); | |
57 Dimension strSize = FigureUtilities.getStringExtents(string, font); | |
58 Image srcImage = new Image(display, strSize.width, metrics.getAscent()); | |
59 GC gc = new GC(srcImage); | |
60 gc.setFont(font); | |
61 gc.setForeground(foreground); | |
62 gc.setBackground(background); | |
63 gc.fillRectangle(srcImage.getBounds()); | |
64 gc.drawString(string, 0, 0 - metrics.getLeading()); | |
65 Image result = createRotatedImage(srcImage); | |
66 gc.dispose(); | |
67 srcImage.dispose(); | |
68 return result; | |
69 } | |
70 | |
71 /** | |
72 * Returns a new Image that is the given Image rotated left by 90 degrees. The client is | |
73 * responsible for disposing the returned Image. This method MUST be invoked from the | |
74 * user-interface (Display) thread. | |
75 * | |
76 * @param srcImage the Image that is to be rotated left | |
77 * @return the rotated Image (the client is responsible for disposing it) | |
78 */ | |
79 public static Image createRotatedImage(Image srcImage) { | |
80 Display display = Display.getCurrent(); | |
81 if (display is null) | |
82 DWT.error(DWT.ERROR_THREAD_INVALID_ACCESS); | |
83 | |
84 ImageData srcData = srcImage.getImageData(); | |
85 ImageData destData; | |
86 if (srcData.depth < 8) | |
87 destData = rotatePixelByPixel(srcData); | |
88 else | |
89 destData = rotateOptimized(srcData); | |
90 | |
91 return new Image(display, destData); | |
92 } | |
93 | |
94 /** | |
95 * Creates an ImageData representing the given <code>Image</code> shaded with the given | |
96 * <code>Color</code>. | |
97 * | |
98 * @param fromImage Image that has to be shaded | |
99 * @param shade The Color to be used for shading | |
100 * @return A new ImageData that can be used to create an Image. | |
101 */ | |
102 public static ImageData createShadedImage(Image fromImage, Color shade) { | |
103 dwt.graphics.Rectangle.Rectangle r = fromImage.getBounds(); | |
104 ImageData data = fromImage.getImageData(); | |
105 PaletteData palette = data.palette; | |
106 if (!palette.isDirect) { | |
107 /* Convert the palette entries */ | |
108 RGB [] rgbs = palette.getRGBs(); | |
109 for (int i = 0; i < rgbs.length; i++) { | |
110 if (data.transparentPixel !is i) { | |
111 RGB color = rgbs [i]; | |
112 color.red = determineShading(color.red, shade.getRed()); | |
113 color.blue = determineShading(color.blue, shade.getBlue()); | |
114 color.green = determineShading(color.green, shade.getGreen()); | |
115 } | |
116 } | |
117 data.palette = new PaletteData(rgbs); | |
118 } else { | |
119 /* Convert the pixels. */ | |
120 int[] scanline = new int[r.width]; | |
121 int redMask = palette.redMask; | |
122 int greenMask = palette.greenMask; | |
123 int blueMask = palette.blueMask; | |
124 int redShift = palette.redShift; | |
125 int greenShift = palette.greenShift; | |
126 int blueShift = palette.blueShift; | |
127 for (int y = 0; y < r.height; y++) { | |
128 data.getPixels(0, y, r.width, scanline, 0); | |
129 for (int x = 0; x < r.width; x++) { | |
130 int pixel = scanline[x]; | |
131 int red = pixel & redMask; | |
132 red = (redShift < 0) ? red >>> -redShift : red << redShift; | |
133 int green = pixel & greenMask; | |
134 green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; | |
135 int blue = pixel & blueMask; | |
136 blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; | |
137 red = determineShading(red, shade.getRed()); | |
138 blue = determineShading(blue, shade.getBlue()); | |
139 green = determineShading(green, shade.getGreen()); | |
140 red = (redShift < 0) ? red << -redShift : red >> redShift; | |
141 red &= redMask; | |
142 green = (greenShift < 0) ? green << -greenShift : green >> greenShift; | |
143 green &= greenMask; | |
144 blue = (blueShift < 0) ? blue << -blueShift : blue >> blueShift; | |
145 blue &= blueMask; | |
146 scanline[x] = red | blue | green; | |
147 } | |
148 data.setPixels(0, y, r.width, scanline, 0); | |
149 } | |
150 } | |
151 return data; | |
152 } | |
153 | |
154 private static int determineShading(int origColor, int shadeColor) { | |
155 return (origColor + shadeColor) / 2; | |
156 } | |
157 | |
158 private static ImageData rotateOptimized(ImageData srcData) { | |
159 int bytesPerPixel = Math.max(1, srcData.depth / 8); | |
160 int destBytesPerLine = ((srcData.height * bytesPerPixel - 1) / srcData.scanlinePad + 1) | |
161 * srcData.scanlinePad; | |
162 byte[] newData = new byte[destBytesPerLine * srcData.width]; | |
163 for (int srcY = 0; srcY < srcData.height; srcY++) { | |
164 for (int srcX = 0; srcX < srcData.width; srcX++) { | |
165 int destX = srcY; | |
166 int destY = srcData.width - srcX - 1; | |
167 int destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel); | |
168 int srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel); | |
169 System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel); | |
170 } | |
171 } | |
172 return new ImageData(srcData.height, srcData.width, srcData.depth, srcData.palette, | |
173 srcData.scanlinePad, newData); | |
174 } | |
175 | |
176 private static ImageData rotatePixelByPixel(ImageData srcData) { | |
177 ImageData destData = new ImageData(srcData.height, srcData.width, srcData.depth, | |
178 srcData.palette); | |
179 for (int y = 0; y < srcData.height; y++) { | |
180 for (int x = 0; x < srcData.width; x++) { | |
181 destData.setPixel(y, srcData.width - x - 1, srcData.getPixel(x, y)); | |
182 } | |
183 } | |
184 return destData; | |
185 } | |
186 | |
187 } |