📄 pixeldrawing.java
字号:
byte [] row = layerBitMap[y]; for(int x=0; x<numBytesPerRow; x++) row[x] = 0; } } // erase the patterned opaque layer bitmaps assert patternedOpaqueLayers.isEmpty(); // empty at top level for(Iterator<PatternedOpaqueLayer> it = patternedOpaqueLayers.values().iterator(); it.hasNext(); ) { PatternedOpaqueLayer pol = it.next(); byte [][] layerBitMap = pol.layerBitMap; for(int y=0; y<sz.height; y++) { byte [] row = layerBitMap[y]; for(int x=0; x<numBytesPerRow; x++) row[x] = 0; } } // erase opaque image if (bounds == null) { // erase the entire image for(int i=0; i<total; i++) opaqueData[i] = backgroundValue; } else { // erase only part of the image int lx = bounds.x; int hx = lx + bounds.width; int ly = bounds.y; int hy = ly + bounds.height; if (lx < 0) lx = 0; if (hx >= sz.width) hx = sz.width - 1; if (ly < 0) ly = 0; if (hy >= sz.height) hy = sz.height - 1; for(int y=ly; y<=hy; y++) { int baseIndex = y * sz.width; for(int x=lx; x<=hx; x++) opaqueData[baseIndex + x] = backgroundValue; } } } /** * Method to complete rendering by combining the transparent and opaque imagery. * This is called after all rendering is done. * @return the offscreen Image with the final display. */ public Image composite(Rectangle bounds) { // merge in the transparent layers if (numLayerBitMapsCreated > 0) { // get the technology's color map Color [] colorMap = curTech.getColorMap(); // adjust the colors if any of the transparent layers are dimmed boolean dimmedTransparentLayers = false; for(Iterator<Layer> it = curTech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); if (!layer.isDimmed()) continue; if (layer.getGraphics().getTransparentLayer() == 0) continue; dimmedTransparentLayers = true; break; } if (dimmedTransparentLayers) { Color [] newColorMap = new Color[colorMap.length]; int numTransparents = curTech.getNumTransparentLayers(); boolean [] dimLayer = new boolean[numTransparents]; for(int i=0; i<numTransparents; i++) dimLayer[i] = true; for(Iterator<Layer> it = curTech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); if (layer.isDimmed()) continue; int tIndex = layer.getGraphics().getTransparentLayer(); if (tIndex == 0) continue; dimLayer[tIndex-1] = false; } for(int i=0; i<colorMap.length; i++) { newColorMap[i] = colorMap[i]; if (i == 0) continue; boolean dimThisEntry = true; for(int j=0; j<numTransparents; j++) { if ((i & (1<<j)) != 0) { if (!dimLayer[j]) { dimThisEntry = false; break; } } } if (dimThisEntry) { newColorMap[i] = new Color(dimColor(colorMap[i].getRGB())); } else { newColorMap[i] = new Color(brightenColor(colorMap[i].getRGB())); } } colorMap = newColorMap; } // determine range int lx = 0, hx = sz.width-1; int ly = 0, hy = sz.height-1; if (bounds != null) { lx = bounds.x; hx = lx + bounds.width; ly = bounds.y; hy = ly + bounds.height; if (lx < 0) lx = 0; if (hx >= sz.width) hx = sz.width - 1; if (ly < 0) ly = 0; if (hy >= sz.height) hy = sz.height - 1; } for(int y=ly; y<=hy; y++) { for(int i=0; i<numLayerBitMaps; i++) { byte [][] layerBitMap = layerBitMaps[i]; if (layerBitMap == null) compositeRows[i] = null; else { compositeRows[i] = layerBitMap[y]; } } int baseIndex = y * sz.width; for(int x=lx; x<=hx; x++) { int index = baseIndex + x; int pixelValue = opaqueData[index]; // the value of Alpha starts at 0xFF, which means "background" // opaque drawing typically sets it to 0, which means "filled" // Text drawing can antialias by setting the edge values in the range 0-254 // where the lower the value, the more saturated the color (so 0 means all color, 254 means little color) int alpha = (pixelValue >> 24) & 0xFF; if (alpha != 0) { // aggregate the transparent bitplanes at this pixel int bits = 0; int entry = x >> 3; int maskBit = 1 << (x & 7); for(int i=0; i<numLayerBitMaps; i++) { if (compositeRows[i] == null) continue; int byt = compositeRows[i][entry]; if ((byt & maskBit) != 0) bits |= (1<<i); } // determine the transparent color to draw int newColor = backgroundColor; if (bits != 0) { // set a transparent color newColor = colorMap[bits].getRGB() & 0xFFFFFF; } // if alpha blending, merge with the opaque data if (alpha != 0xFF) { newColor = alphaBlend(pixelValue, newColor, alpha); } opaqueData[index] = newColor; } } } } else { // nothing in transparent layers: make sure background color is right if (bounds == null) { // handle the entire image for(int i=0; i<total; i++) { int pixelValue = opaqueData[i]; if (pixelValue == backgroundValue) opaqueData[i] = backgroundColor; else { if ((pixelValue&0xFF000000) != 0) { int alpha = (pixelValue >> 24) & 0xFF; opaqueData[i] = alphaBlend(pixelValue, backgroundColor, alpha); } } } } else { // handle a partial image int lx = bounds.x; int hx = lx + bounds.width; int ly = bounds.y; int hy = ly + bounds.height; if (lx < 0) lx = 0; if (hx >= sz.width) hx = sz.width - 1; if (ly < 0) ly = 0; if (hy >= sz.height) hy = sz.height - 1; for(int y=ly; y<=hy; y++) { int baseIndex = y * sz.width; for(int x=lx; x<=hx; x++) { int index = baseIndex + x; int pixelValue = opaqueData[index]; if (pixelValue == backgroundValue) opaqueData[index] = backgroundColor; else { if ((pixelValue&0xFF000000) != 0) { int alpha = (pixelValue >> 24) & 0xFF; opaqueData[index] = alphaBlend(pixelValue, backgroundColor, alpha); } } } } } } return img; } /** * Method to draw the grid into the offscreen buffer */ private void drawGrid(EditWindow wnd, WindowFrame.DisplayAttributes da) { double spacingX = wnd.getGridXSpacing(); double spacingY = wnd.getGridYSpacing(); if (spacingX == 0 || spacingY == 0) return; double boldSpacingX = spacingX * User.getDefGridXBoldFrequency(); double boldSpacingY = spacingY * User.getDefGridYBoldFrequency(); double boldSpacingThreshX = spacingX / 4; double boldSpacingThreshY = spacingY / 4; // screen extent Rectangle2D displayable = displayableBounds(da.getIntoCellTransform()); double lX = displayable.getMinX(); double lY = displayable.getMaxY(); double hX = displayable.getMaxX(); double hY = displayable.getMinY(); double scaleX = sz.width / (hX - lX); double scaleY = sz.height / (lY - hY); // initial grid location double x1 = DBMath.toNearest(lX, spacingX); double y1 = DBMath.toNearest(lY, spacingY); // adjust grid placement according to scale boolean allBoldDots = false; if (spacingX * scaleX < 5 || spacingY * scaleY < 5) { // normal grid is too fine: only show the "bold dots" x1 = DBMath.toNearest(x1, boldSpacingX); spacingX = boldSpacingX; y1 = DBMath.toNearest(y1, boldSpacingY); spacingY = boldSpacingY; // if even the bold dots are too close, don't draw a grid if (spacingX * scaleX < 10 || spacingY * scaleY < 10) return; } else if (spacingX * scaleX > 75 && spacingY * scaleY > 75) { // if zoomed-out far enough, show all bold dots allBoldDots = true; } // draw the grid Point2D.Double tmpPt = new Point2D.Double(); AffineTransform outofCellTransform = da.getOutofCellTransform(); int col = User.getColor(User.ColorPrefType.GRID) & 0xFFFFFF; for(double i = y1; i > hY; i -= spacingY) { double boldValueY = i; if (i < 0) boldValueY -= boldSpacingThreshY/2; else boldValueY += boldSpacingThreshY/2; boolean everyTenY = Math.abs(boldValueY) % boldSpacingY < boldSpacingThreshY; for(double j = x1; j < hX; j += spacingX) { tmpPt.setLocation(j, i); outofCellTransform.transform(tmpPt, tmpPt); databaseToScreen(tmpPt.getX(), tmpPt.getY(), tempPt1); int x = tempPt1.x; int y = tempPt1.y; if (x < 0 || x >= sz.width) continue; if (y < 0 || y >= sz.height) continue; double boldValueX = j; if (j < 0) boldValueX -= boldSpacingThreshX/2; else boldValueX += boldSpacingThreshX/2; boolean everyTenX = Math.abs(boldValueX) % boldSpacingX < boldSpacingThreshX; if (allBoldDots && everyTenX && everyTenY) { int boxLX = x-2; if (boxLX < 0) boxLX = 0; int boxHX = x+2; if (boxHX >= sz.width) boxHX = sz.width-1; int boxLY = y-2; if (boxLY < 0) boxLY = 0; int boxHY = y+2; if (boxHY >= sz.height) boxHY = sz.height-1; drawBox(boxLX, boxHX, boxLY, boxHY, null, gridGraphics, false); if (x > 1) opaqueData[y * sz.width + (x-2)] = col; if (x < sz.width-2) opaqueData[y * sz.width + (x+2)] = col; if (y > 1) opaqueData[(y-2) * sz.width + x] = col; if (y < sz.height-2) opaqueData[(y+2) * sz.width + x] = col; continue; } // special case every 10 grid points in each direction if (allBoldDots || (everyTenX && everyTenY)) { opaqueData[y * sz.width + x] = col; if (x > 0) opaqueData[y * sz.width + (x-1)] = col; if (x < sz.width-1) opaqueData[y * sz.width + (x+1)] = col; if (y > 0) opaqueData[(y-1) * sz.width + x] = col; if (y < sz.height-1) opaqueData[(y+1) * sz.width + x] = col; continue; } // just a single dot opaqueData[y * sz.width + x] = col; } } if (User.isGridAxesShown()) { tmpPt.setLocation(0, 0); outofCellTransform.transform(tmpPt, tmpPt); databaseToScreen(tmpPt.getX(), tmpPt.getY(), tempPt1); int x = tempPt1.x; int y = tempPt1.y; if (x >= 0 && x < sz.width) drawSolidLine(x, 0, x, sz.height-1, null, col); if (y >= 0 && y < sz.height) drawSolidLine(0, y, sz.width-1, y, null, col); } } /** * Method to return a rectangle in database coordinates that covers the viewable extent of this window. * @return a rectangle that describes the viewable extent of this window (database coordinates). */ private Rectangle2D displayableBounds(AffineTransform intoCellTransform) { Point2D low = new Point2D.Double(); screenToDatabase(0, 0, low); intoCellTransform.transform(low, low); Point2D high = new Point2D.Double(); screenToDatabase(sz.width-1, sz.height-1, high); intoCellTransform.transform(high, high);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -