All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fit.cssbox.layout.CSSDecoder Maven / Gradle / Ivy

Go to download

CSSBox is an (X)HTML/CSS rendering engine written in pure Java. Its primary purpose is to provide a complete information about the rendered page suitable for further processing. However, it also allows displaying the rendered document.

There is a newer version: 5.0.2
Show newest version
/*
 * CSSDecoder.java
 * Copyright (c) 2005-2007 Radek Burget
 *
 * CSSBox is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * CSSBox is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *  
 * You should have received a copy of the GNU Lesser General Public License
 * along with CSSBox. If not, see .
 *
 * Created on 7. zari 2005, 15:39
 */

package org.fit.cssbox.layout;

import java.awt.Rectangle;

import org.fit.cssbox.css.HTMLNorm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;

import cz.vutbr.web.css.*;

/**
 * This class implements converting the CSS specifications to Java data types.
 *
 * @author  burgetr
 */
public class CSSDecoder 
{
    protected static Logger log = LoggerFactory.getLogger(CSSDecoder.class);

    private VisualContext context;
    
    /**
     * Creates a new VisualDecoder in the specified context. The context is
     * used for the unit conversion (e.g. the em units etc.)
     * @param c the visual contect to be assigned  
     */
    public CSSDecoder(VisualContext c)
    {
        context = c;
    }
    
    /**
     * Returns the visual context of this decoder.
     * @return the assigned visual context
     */
    public VisualContext getContext()
    {
        return context;
    }

    /**
     * Changes the visual context assigned to this decoder.
     * @param c The new visual context to be assigned
     */
    public void setContext(VisualContext c)
    {
        context = c;
    }
    
    /** 
     * Returns the length in pixels from a CSS definition. null values
     * of the lengths are interpreted as zero.
     * @param value The length or percentage value to be converted
     * @param auto True, if the property is set to auto
     * @param defval The length value to be used when the first one is null
     * @param autoval The value to be used when "auto" is specified
     * @param whole the length to be returned as 100% (in case of percentage values)
     */
    public int getLength(TermLengthOrPercent value, boolean auto, TermLengthOrPercent defval, TermLengthOrPercent autoval, int whole)
    {
        TermLengthOrPercent val = value;
        if (value == null) val = defval;
        if (auto) val = autoval;
        if (val != null)
            return (int) context.pxLength(val, whole);
        else
        	return 0;
    }
    
    /** 
     * Returns the length in pixels from a CSS definition
     * @param value The length or percentage value to be converted
     * @param auto True, if the property is set to auto
     * @param defval The length value to be used when the first one is null
     * @param autoval The value to be used when "auto" is specified
     * @param whole the length to be returned as 100% (in case of percentage values)
     */
    public int getLength(TermLengthOrPercent value, boolean auto, int defval, int autoval, int whole)
    {
        if (auto)
            return autoval;
        else if (value == null)
            return defval;
        else
            return (int) context.pxLength(value, whole);
    }
    
    /**
     * Computes the width and height of a replaced object based on the following properties:
     * 
    *
  • Intrinsic width and height
  • *
  • The width and height attributes
  • *
  • Effective style
  • *
* @param obj The replaced content object * @param box The element box whose size should be computed * @return A rectangle with the width and height set accordingly */ public static Rectangle computeReplacedObjectSize(ReplacedContent obj, ElementBox box) { int boxw; //resulting size int boxh; int intw; //intrinsic sizes int inth; float intr; if (obj != null) { intw = obj.getIntrinsicWidth(); inth = obj.getIntrinsicHeight(); if (intw == 0 || inth == 0) { log.warn("Obtained a zero intrinsic width or height for " + obj.toString()); intw = inth = 1; //a fallback for avoiding zeros in ratios } intr = (float) intw / inth; boxw = intw; boxh = inth; } else { boxw = intw = 20; //some reasonable default values boxh = inth = 20; intr = 1.0f; } //total widths used for percentages int twidth = box.getContainingBlock().getContentWidth(); int theight = box.getViewport().getContentHeight(); //try to use the attributes Element el = box.getElement(); int atrw = -1; int atrh = -1; try { if (!el.getAttribute("width").equals("")) atrw = HTMLNorm.computeAttributeLength(el.getAttribute("width"), twidth); } catch (NumberFormatException e) { log.info("Invalid width value: " + el.getAttribute("width")); } try { if (!el.getAttribute("height").equals("")) atrh = HTMLNorm.computeAttributeLength(el.getAttribute("height"), theight); } catch (NumberFormatException e) { log.info("Invalid height value: " + el.getAttribute("width")); } //apply intrinsic ration when necessary if (atrw == -1 && atrh == -1) { boxw = intw; boxh = inth; } else if (atrw == -1) { boxw = Math.round(intr * atrh); boxh = atrh; } else if (atrh == -1) { boxw = atrw; boxh = Math.round(atrw / intr); } else { boxw = atrw; boxh = atrh; intr = (float) boxw / boxh; //new intrsinsic ratio is set explicitly } //compute dimensions from styles (styles should override the attributes) CSSDecoder dec = new CSSDecoder(box.getVisualContext()); CSSProperty.Width width = box.getStyle().getProperty("width"); if (width == CSSProperty.Width.AUTO) width = null; //auto and null are equal for width CSSProperty.Height height = box.getStyle().getProperty("height"); if (height == CSSProperty.Height.AUTO) height = null; //auto and null are equal for height if (width == null && height != null) { //compute boxh, boxw is intrinsic int autoh = Math.round(boxw / intr); boxh = dec.getLength(box.getLengthValue("height"), height == CSSProperty.Height.AUTO, boxh, autoh, theight); boxw = Math.round(intr * boxh); } else if (width != null && height == null) { //compute boxw, boxh is intrinsic int autow = Math.round(intr * boxh); boxw = dec.getLength(box.getLengthValue("width"), width == CSSProperty.Width.AUTO, boxw, autow, twidth); boxh = Math.round(boxw / intr); } else { boxw = dec.getLength(box.getLengthValue("width"), width == CSSProperty.Width.AUTO, boxw, intw, twidth); boxh = dec.getLength(box.getLengthValue("height"), height == CSSProperty.Height.AUTO, boxh, inth, theight); } return new Rectangle(boxw, boxh); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy