com.google.eclipse.elt.emulator.textcanvas.StyleMap.java Source code

Java tutorial

Introduction

Here is the source code for com.google.eclipse.elt.emulator.textcanvas.StyleMap.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package com.google.eclipse.elt.emulator.textcanvas;

import java.util.*;

import org.eclipse.jface.resource.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Display;

import com.google.eclipse.elt.emulator.model.*;

public class StyleMap {
    private static final String BLACK = "black";
    private static final String WHITE = "white";
    private static final String WHITE_FOREGROUND = "white_foreground";
    private static final String GRAY = "gray";
    private static final String MAGENTA = "magenta";
    private static final String CYAN = "cyan";
    private static final String YELLOW = "yellow";
    private static final String BLUE = "blue";
    private static final String GREEN = "green";
    private static final String RED = "red";

    private static final String PREFIX = "org.eclipse.tm.internal.";

    private final Map<StyleColor, Color> colorMapForeground = new HashMap<StyleColor, Color>();
    private final Map<StyleColor, Color> colorMapBackground = new HashMap<StyleColor, Color>();
    private final Map<StyleColor, Color> colorMapIntense = new HashMap<StyleColor, Color>();

    private Point charSize;

    private boolean invertColors;
    private boolean proportional;

    private final int[] offsets = new int[256];

    private Color background = getColor(new RGB(0, 0, 0));
    private Color foreground = getColor(new RGB(229, 229, 229));

    private Font font = JFaceResources.getFontRegistry().get("org.eclipse.jface.textfont");

    StyleMap() {
        initColors();
        updateFont();
    }

    private void initColors() {
        initForegroundColors();
        initBackgroundColors();
        initIntenseColors();
    }

    private void initForegroundColors() {
        if (invertColors) {
            setColor(colorMapForeground, WHITE, 0, 0, 0);
            setColor(colorMapForeground, WHITE_FOREGROUND, 50, 50, 50);
            setColor(colorMapForeground, BLACK, 229, 229, 229);
        } else {
            setColor(colorMapForeground, WHITE, 255, 255, 255);
            setColor(colorMapForeground, WHITE_FOREGROUND, 229, 229, 229);
            setColor(colorMapForeground, BLACK, 50, 50, 50);
        }
        setColor(colorMapForeground, RED, 205, 0, 0);
        setColor(colorMapForeground, GREEN, 0, 205, 0);
        setColor(colorMapForeground, BLUE, 0, 0, 238);
        setColor(colorMapForeground, YELLOW, 205, 205, 0);
        setColor(colorMapForeground, CYAN, 0, 205, 205);
        setColor(colorMapForeground, MAGENTA, 205, 0, 205);
        setColor(colorMapForeground, GRAY, 229, 229, 229);
    }

    private void initBackgroundColors() {
        if (invertColors) {
            setColor(colorMapBackground, WHITE, 0, 0, 0);
            setColor(colorMapBackground, WHITE_FOREGROUND, 50, 50, 50); // only used when colors are inverse
            setColor(colorMapBackground, BLACK, 255, 255, 255); // cursor color
        } else {
            setColor(colorMapBackground, WHITE, 255, 255, 255);
            setColor(colorMapBackground, WHITE_FOREGROUND, 229, 229, 229);
            setColor(colorMapBackground, BLACK, 0, 0, 0);
        }
        setColor(colorMapBackground, RED, 205, 0, 0);
        setColor(colorMapBackground, GREEN, 0, 205, 0);
        setColor(colorMapBackground, BLUE, 0, 0, 238);
        setColor(colorMapBackground, YELLOW, 205, 205, 0);
        setColor(colorMapBackground, CYAN, 0, 205, 205);
        setColor(colorMapBackground, MAGENTA, 205, 0, 205);
        setColor(colorMapBackground, GRAY, 229, 229, 229);
    }

    private void initIntenseColors() {
        if (invertColors) {
            setColor(colorMapIntense, WHITE, 127, 127, 127);
            setColor(colorMapIntense, WHITE_FOREGROUND, 0, 0, 0); // only used when colors are inverse
            setColor(colorMapIntense, BLACK, 255, 255, 255);
        } else {
            setColor(colorMapIntense, WHITE, 255, 255, 255);
            setColor(colorMapIntense, WHITE_FOREGROUND, 255, 255, 255);
            setColor(colorMapIntense, BLACK, 0, 0, 0);
        }
        setColor(colorMapIntense, RED, 255, 0, 0);
        setColor(colorMapIntense, GREEN, 0, 255, 0);
        setColor(colorMapIntense, BLUE, 92, 92, 255);
        setColor(colorMapIntense, YELLOW, 255, 255, 0);
        setColor(colorMapIntense, CYAN, 0, 255, 255);
        setColor(colorMapIntense, MAGENTA, 255, 0, 255);
        setColor(colorMapIntense, GRAY, 255, 255, 255);
    }

    private void setColor(Map<StyleColor, Color> colorMap, String name, int r, int g, int b) {
        Color color = getColor(new RGB(r, g, b));
        setColor(colorMap, color, StyleColor.getStyleColor(name));
        setColor(colorMap, color, StyleColor.getStyleColor(name.toUpperCase()));
    }

    private void setColor(Map<StyleColor, Color> colorMap, Color color, StyleColor styleColor) {
        if (styleColor != null) {
            colorMap.put(styleColor, color);
        }
    }

    public Color getForegroundColor(Style style) {
        if (style == null) {
            return foreground;
        }
        StyleColor color = style.isReverse() ? style.getBackground() : style.getForeground();
        Map<StyleColor, Color> map = style.isBold() ? colorMapIntense : colorMapForeground;
        Color actualColor = map.get(color);
        if (actualColor == null) {
            actualColor = foreground;
        }
        return actualColor;
    }

    public Color getBackgroundColor(Style style) {
        if (style == null) {
            return background;
        }
        StyleColor color = style.isReverse() ? style.getForeground() : style.getBackground();
        Color actualColor = colorMapBackground.get(color);
        if (actualColor == null) {
            actualColor = background;
        }
        return actualColor;
    }

    public void setInvertedColors(boolean invert) {
        if (invert == invertColors) {
            return;
        }
        invertColors = invert;
        initColors();
    }

    public Font getFont(Style style) {
        if (style == null) {
            return font;
        }
        FontData fontDatas[] = font.getFontData();
        FontData data = fontDatas[0];
        if (style.isBold()) {
            return new Font(font.getDevice(), data.getName(), data.getHeight(), data.getStyle() | SWT.BOLD);
        }
        if (style.isUnderline()) {
            return new Font(font.getDevice(), data.getName(), data.getHeight(), data.getStyle() | SWT.ITALIC);
        }
        return font;
    }

    public Font getFont() {
        return font;
    }

    public int getFontWidth() {
        return charSize.x;
    }

    public int getFontHeight() {
        return charSize.y;
    }

    public void updateFont() {
        Display display = Display.getCurrent();
        GC gc = new GC(display);
        gc.setFont(font);
        charSize = gc.textExtent("W");
        proportional = false;
        for (char c = ' '; c <= '~'; c++) {
            // Consider only the first 128 chars for deciding if a font is proportional.
            if (measureChar(gc, c, true)) {
                proportional = true;
            }
        }
        // TODO should we also consider the upper 128 chars?
        for (char c = ' ' + 128; c <= '~' + 128; c++) {
            measureChar(gc, c, false);
        }
        if (proportional) {
            charSize.x -= 2; // Works better on small fonts.
        }
        for (int i = 0; i < offsets.length; i++) {
            offsets[i] = (charSize.x - offsets[i]) / 2;
        }
        gc.dispose();
    }

    private boolean measureChar(GC gc, char c, boolean updateMax) {
        boolean proportional = false;
        Point extent = gc.textExtent(String.valueOf(c));
        if (extent.x > 0 && extent.y > 0 && (charSize.x != extent.x || charSize.y != extent.y)) {
            proportional = true;
            if (updateMax) {
                charSize.x = Math.max(charSize.x, extent.x);
                charSize.y = Math.max(charSize.y, extent.y);
            }
        }
        offsets[c] = extent.x;
        return proportional;
    }

    public boolean isFontProportional() {
        return proportional;
    }

    /**
     * Return the offset in pixels required to center a given character.
     *
     * @param c the character to measure.
     * @return the offset in x direction to center this character.
     */
    public int getCharOffset(char c) {
        if (c >= offsets.length) {
            return 0;
        }
        return offsets[c];
    }

    public void setColors(RGB background, RGB foreground) {
        this.background = getColor(background);
        this.foreground = getColor(foreground);
    }

    private Color getColor(RGB colorData) {
        String name = PREFIX + colorData.red + "-" + colorData.green + "-" + colorData.blue;
        ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
        Color color = colorRegistry.get(name);
        if (color == null) {
            colorRegistry.put(name, colorData);
            color = colorRegistry.get(name);
        }
        return color;
    }

    public void setFont(Font font) {
        this.font = font;
        updateFont();
    }
}