/* MessageFlobFactory.zob * * Copyright (c) 2000, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software 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 README * file for more details. * */ /* * Written by Rauli Ruohonen */ package org.gzigzag.module; import org.gzigzag.module.multimedia.*; import org.gzigzag.*; import java.awt.*; import java.util.*; public class MessageFlobFactory implements FlobFactory, ZOb { public static boolean dbg = false; private static void p(String s) { if(dbg) ZZLogger.log(s); } private static void pa(String s) { ZZLogger.log(s); } private String d_image = "d.images"; private String d_text = "d.text"; private String d_author = "d.author"; private String d_handle = "d.kahva"; private MediaFlobFactory mediafact=new MediaFlobFactory(); private FTextLayouter ftext=new FTextLayouter(); SceneFlob mysflob = null; VirtualCommunity vc= null; STRUCTPARAMS { /* In pixels. */ int imgtxt_separator = 0; /* Originally 1/Ph = img_h/txt_h =~ 0.618. (Ph = Golden Ratio) */ float imgtxt_min_ratio = (float)(2.0/(Math.sqrt(5.0)+1.0)); ScalableFont font = new ScalableFont("SansSerif", Font.PLAIN, 12); /* color of the author blob */ Color authorColor = Color.yellow.brighter(); /* color of the message blob */ Color messageColor = new Color(0xffff8c); Color auth_bg = new Color(0xffff28); int border = 3; int clipborder = 2; } public MessageFlobFactory(VirtualCommunity vc){ this.vc = vc; } public MessageFlobFactory(){ } private Color back = Color.white; private FText makeFText(ZZCell c, ZZCell hc,float fract) { Vector a=new Vector(); int scale=(int)(fract*1000); Font f=font.getFont(scale); FontMetrics fm=font.getFontMetrics(scale); Color fg=Color.black;//,bg=Color.white; LoopDetector l=new LoopDetector(); c = c.s(d_text,1); Color fgt = fg; while(c!=null) { fgt = fg; l.detect(c); /*if( c.s(d_handle,1) != null || c.s(d_handle,-1) != null){ fgt = Color.red; }*/ a.addElement(new FText.CellPart(c,c,0,-1,f,fm,null,fgt)); //a.addElement(new FText.StringPart(c.getText(),f,fm,back,fgt)); c=c.s(d_text); } return new FText(a); } public SceneFlob getSFlob(){ return mysflob; } private int cacheW = -1; private Dimension cacheTxt; private ZZCell cacheC; private float cacheFract; private void getSizes(ZZCell c,float fract,int w,int h,Dimension img, Dimension txt) { final int MAGIC=2147483647; ZZCell imgc=c.h(d_image,true); ZZCell textc=c.s(d_text); img.width=0; img.height=0; txt.width=0; txt.height=0; /* Calculate the maximum sizes for both image and text */ if(imgc!=null) img.setSize(mediafact.getSize(imgc,fract)); float aspect=img.width*1.0f/img.height; if(textc!=null) { if (cacheW == w && cacheFract == fract && c.equals(cacheC)) txt.setSize(cacheTxt); else { cacheTxt = ftext.place(null,makeFText(c,c,fract), new Rectangle(0,0,w,MAGIC), 1,1,0,0xdeadbeef,false).getSize(); cacheW = w; cacheC = c; cacheFract = fract; txt.setSize(cacheTxt); } } // Subj. + Auth. txt.height += (font.getFontMetrics((int)(1000 * fract)). getHeight())*2; if (imgc == null) { txt.height = h; return; } if (textc == null) { img.height=h-txt.height; img.width=(int)(img.height*aspect); if(img.width>w) { img.width=w; img.height=(int)(img.width/aspect); } txt.height = h-img.height; return; } h-=imgtxt_separator; float imgtxt_ratio=(h-txt.height)/txt.height; // Text size constant p("it_rat="+imgtxt_ratio); if(imgtxt_ratio 0) x = p.x - d.width; if(yalign < 0) y = p.y; if(yalign > 0) y = p.y - d.height; return makeFlob(into, c, handleCell, fract, x, y, depth, d.width, d.height); } public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell, float fract, Point p, int xalign, int yalign, int depth) { return centerFlob(into, c, handleCell, fract, p, xalign, yalign, depth, null); } public Flob makeSubject(FlobSet into, ZZCell c, ZZCell handleCell, float fract, int x, int y, int depth, int w, Flob parent, int mh) { if (mh > 100) mh = 100; Flob sc = new SubjCell(x,y,depth,w,mh,c, handleCell, fract); sc.setParent(parent); into.add(sc); return sc; } public Flob makeAuthor(FlobSet into, ZZCell c, ZZCell handleCell, float fract, int x, int y, int depth, int w, float xfract, float yfract, Flob parent, int mh) { if (mh > 100) mh = 100; Flob ac = new AuthCell(x,y,depth,w,mh,c, handleCell, fract); ac.setParent(parent); into.add(ac); return ac; } /** * Flob for message subjects */ class SubjCell extends Flob { int ascent; float fr; ZZCell handle; public SubjCell(int x, int y, int d, int w, int h, ZZCell c, ZZCell hc, float fract){ super(x,y,d,w,h,c); Font f = font.getFont((int)(1000 * fract)); FontMetrics fm = font.getFontMetrics((int)(1000 * fract)); ascent = fm.getAscent(); this.h = fm.getHeight(); if (this.h > h) this.h = h; //this.w = fm.stringWidth("Subject: " +c.getText()); fr = fract; handle = hc; //p("FR = " + fr); } public void renderInterp(Graphics g, float fract) { return; } public void render(Graphics g, int mx, int my, int md, int mw, int mh) { /*ZZDrawingJ2D drw = null; if (ZZDrawing.instance instanceof ZZDrawingJ2D) drw = (ZZDrawingJ2D)ZZDrawing.instance; if (drw != null) { drw.setFIXME(false); drw.setQuality(g); }*/ FontMetrics fm = font.getFontMetrics((int)(1000 * fr)); Color old = g.getColor(); g.setFont(font.getFont((int)(fr*1000))); g.setColor(auth_bg); Rectangle asd=g.getClipBounds(); // g.setClip(mx-clipborder,my-clipborder,mw+clipborder*2,mh+clipborder*2); g.fillRect(mx,my,mw,mh); g.setColor(old); /*if (drw != null) { drw.setFIXME(true); drw.setQuality(g); }*/ if( fm.stringWidth("Subject: " + c.getText()) > mw ) g.drawString( c.getText(), mx,my+ascent); else g.drawString("Subject: " + c.getText(), mx,my+ascent); //g.drawLine(mx, my+h, mx+w, my+h); // g.setClip(asd); } public Object hit(int x0, int y0) { if( x0 >= x && y0 >= y && x0 < x+w && y0 < y+h ) return handle; return null; } } /** * Flob for message auth */ class AuthCell extends Flob { int ascent; int height; ZZCell handle; float fr = 1.0f; public AuthCell(int x, int y, int d, int w, int h, ZZCell c, ZZCell hc, float fract){ super(x,y,d,w,h,c); Font f = font.getFont((int)(1000 * fract)); FontMetrics fm = font.getFontMetrics((int)(1000 * fract)); ascent = fm.getAscent(); this.h = fm.getHeight(); if (this.h > h) this.h = h; //this.w = fm.stringWidth("Author: " + c.getText()); fr = fract; handle = hc; } public void renderInterp(Graphics g, float fract) { return; } public void render(Graphics g, int mx, int my, int md, int mw, int mh) { /*ZZDrawingJ2D drw = null; if (ZZDrawing.instance instanceof ZZDrawingJ2D) drw = (ZZDrawingJ2D)ZZDrawing.instance; if (drw != null) { drw.setFIXME(false); drw.setQuality(g); }*/ Color old = g.getColor(); FontMetrics fm = font.getFontMetrics((int)(1000 * fr)); g.setFont(font.getFont((int)(1000 * fr))); Rectangle asd=g.getClipBounds(); // g.setClip(mx-clipborder,my-clipborder,mw+clipborder*2,mh+clipborder*2); g.setColor(auth_bg); g.fillRect(mx,my,mw,mh); g.setColor(old); /*if (drw != null) { drw.setFIXME(true); drw.setQuality(g); }*/ if( fm.stringWidth("Author: " + c.getText()) < mw ) g.drawString("Author: " + c.getText(), mx,my+ascent); else g.drawString( c.getText(), mx,my+ascent); g.drawLine(mx, my+mh-1, mx+mw, my+mh-1); // g.setClip(asd); } public Object hit(int x0, int y0) { if( x0 >= x && y0 >= y && x0 < x+w && y0 < y+h ) return handle; return null; } } } // vim: set syntax=java :