Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/X11CustomCursor.java
32287 views
/*1* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt;2627import sun.awt.CustomCursor;28import java.awt.*;29import java.awt.image.*;30import sun.awt.image.ImageRepresentation;3132/**33* A class to encapsulate a custom image-based cursor.34*35* @see Component#setCursor36* @author Thomas Ball37*/38public abstract class X11CustomCursor extends CustomCursor {3940public X11CustomCursor(Image cursor, Point hotSpot, String name)41throws IndexOutOfBoundsException {42super(cursor, hotSpot, name);43}4445protected void createNativeCursor(Image im, int[] pixels, int width, int height,46int xHotSpot, int yHotSpot) {4748class CCount implements Comparable {49int color;50int count;5152public CCount(int cl, int ct) {53color = cl;54count = ct;55}5657public int compareTo(Object cc) {58return ((CCount)cc).count - count;59}60}6162int tmp[] = new int[pixels.length];63for (int i=0; i<pixels.length; i++) {64if ((pixels[i] & 0xff000000) == 0) {65tmp[i] = -1;66} else {67tmp[i] = pixels[i] & 0x00ffffff;68}69}70java.util.Arrays.sort(tmp);7172int fc = 0x000000;73int bc = 0xffffff;74CCount cols[] = new CCount[pixels.length];7576int is = 0;77int numColors = 0;78while ( is < pixels.length ) {79if (tmp[is] != -1) {80cols[numColors++] = new CCount(tmp[is], 1);81break;82}83is ++;84}8586for (int i = is+1; i < pixels.length; i++) {87if (tmp[i] != cols[numColors-1].color) {88cols[numColors++] = new CCount(tmp[i], 1);89} else {90cols[numColors-1].count ++;91}92}93java.util.Arrays.sort(cols, 0, numColors);9495if (numColors > 0) fc = cols[0].color;96int fcr = (fc >> 16) & 0x000000ff;97int fcg = (fc >> 8) & 0x000000ff;98int fcb = (fc >> 0) & 0x000000ff;99100int rdis = 0;101int gdis = 0;102int bdis = 0;103for (int j = 1; j < numColors; j++) {104int rr = (cols[j].color >> 16) & 0x000000ff;105int gg = (cols[j].color >> 8) & 0x000000ff;106int bb = (cols[j].color >> 0) & 0x000000ff;107rdis = rdis + cols[j].count * rr;108gdis = gdis + cols[j].count * gg;109bdis = bdis + cols[j].count * bb;110}111int rest = pixels.length - ((numColors > 0) ? cols[0].count : 0);112// 4653170 Avoid divide / zero exception113if (rest > 0) {114rdis = rdis / rest - fcr;115gdis = gdis / rest - fcg;116bdis = bdis / rest - fcb;117}118rdis = (rdis*rdis + gdis*gdis + bdis*bdis) / 2;119// System.out.println(" rdis is "+ rdis);120121for (int j = 1; j < numColors; j++) {122int rr = (cols[j].color >> 16) & 0x000000ff;123int gg = (cols[j].color >> 8) & 0x000000ff;124int bb = (cols[j].color >> 0) & 0x000000ff;125126if ( (rr-fcr)*(rr-fcr) + (gg-fcg)*(gg-fcg) + (bb-fcb)*(bb-fcb)127>= rdis ) {128bc = cols[j].color;129break;130}131}132int bcr = (bc >> 16) & 0x000000ff;133int bcg = (bc >> 8) & 0x000000ff;134int bcb = (bc >> 0) & 0x000000ff;135136137// On Solaris 2.5.x, the above code for cursor of any size runs fine138// but on Solaris 2.6, the width of a cursor has to be 8 divisible,139// otherwise, the cursor could be displayed as garbaged.140// To work around the 2.6 problem, the following code pads any cursor141// with a transparent area to make a new cursor of width 8 multiples.142// --- Bug 4148455143int wNByte = (width + 7)/8;144int tNByte = wNByte * height;145byte[] xorMask = new byte[tNByte];146byte[] andMask = new byte[tNByte];147148for (int i = 0; i < width; i++) {149int omask = 1 << (i % 8);150for (int j = 0; j < height; j++) {151int ip = j*width + i;152int ibyte = j*wNByte + i/8;153154if ((pixels[ip] & 0xff000000) != 0) {155andMask[ibyte] |= omask;156}157158int pr = (pixels[ip] >> 16) & 0x000000ff;159int pg = (pixels[ip] >> 8) & 0x000000ff;160int pb = (pixels[ip] >> 0) & 0x000000ff;161if ( (pr-fcr)*(pr-fcr) + (pg-fcg)*(pg-fcg) + (pb-fcb)*(pb-fcb)162<= (pr-bcr)*(pr-bcr) + (pg-bcg)*(pg-bcg) + (pb-bcb)*(pb-bcb) ) {163// show foreground color164xorMask[ibyte] |= omask;165}166}167}168169createCursor(xorMask, andMask, 8*wNByte, height, fc, bc, xHotSpot, yHotSpot);170}171172protected abstract void createCursor(byte[] xorMask, byte[] andMask,173int width, int height,174int fcolor, int bcolor,175int xHotSpot, int yHotSpot);176177}178179180