2012-08-28 6 views
5

sto cercando di disegnare un rettangolo intorno a un elemento di testo utilizzando getBBox(), il codice è piuttosto semplice, creare un documento, aggiungere elemento di testo, documenti di avvio e aggiungere rettangolo. Il problema è che getBBox sta restituendo alcuni valori strani, mi manca qualcosa?valori errati di rettangolo di selezione per l'elemento di testo utilizzando Batik

DOMImplementation impl; 
String svgNS; 
SVGDocument doc; 
Element svgRoot; 

UserAgent userAgent; 
DocumentLoader loader; 
BridgeContext ctx; 
GVTBuilder builder; 
GraphicsNode rootGN; 

... 

// get a DOM and create a document 
impl = SVGDOMImplementation.getDOMImplementation(); 
svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; 
doc = (SVGDocument)impl.createDocument(svgNS, "svg", null); 

// Get (the 'svg' element). 
svgRoot = doc.getDocumentElement(); 

// Set the width and height attributes on the root 'svg' element. 
svgRoot.setAttributeNS(svgNS, "width", "400"); 
svgRoot.setAttributeNS(svgNS, "height", "450"); 

// Add a text element 
Element txtElem = doc.createElementNS(svgNS, "text"); 
txtElem.setAttributeNS(svgNS, "x", "30"); 
txtElem.setAttributeNS(svgNS, "y", "50"); 
txtElem.setAttributeNS(svgNS, "style", "font-family:Arial;font-size:20;stroke:#000000;#fill:#00ff00;"); 
txtElem.setTextContent("sometext"); 

svgRoot.appendChild(txtElem); 

// boot the document 
userAgent = new UserAgentAdapter(); 
loader = new DocumentLoader(userAgent); 
ctx = new BridgeContext(userAgent, loader); 
ctx.setDynamicState(BridgeContext.DYNAMIC); 
builder = new GVTBuilder(); 
rootGN = builder.build(ctx, doc); 

// add a bounding box to text elements 
NodeList nodelist = doc.getElementsByTagName("text"); 
for (int i=0; i < nodelist.getLength(); i++) { 
    SVGOMTextElement textElem = (SVGOMTextElement)nodelist.item(i); 
    SVGRect bbox = textElem.getBBox(); 

    Element rectangle = doc.createElementNS(svgNS, "rect"); 
    rectangle.setAttributeNS(svgNS, "x", new Float(bbox.getX()).toString()); 
    rectangle.setAttributeNS(svgNS, "y", new Float(bbox.getY()).toString()); 
    rectangle.setAttributeNS(svgNS, "width", new Float(bbox.getWidth()).toString()); 
    rectangle.setAttributeNS(svgNS, "height", new Float(bbox.getHeight()).toString()); 
    rectangle.setAttributeNS(svgNS, "fill", "rgba(0,0,0,0)"); 
    rectangle.setAttributeNS(svgNS, "stroke", "#ff0000"); 
    rectangle.setAttributeNS(svgNS, "stroke-width", "1"); 

    svgRoot.appendChild(rectangle); 
} 

questo è il documento in formato SVG che sto ricevendo, come si può vedere il rettangolo ha diversi valori Y (larghezza e altezza sono anche sbagliato) e X.

<?xml version="1.0" encoding="UTF-8"?> 
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" contentScriptType="text/ecmascript" zoomAndPan="magnify" width="400" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" height="450" version="1.0"> 
    <text x="30" style="font-family:Georgia;font-size:20;stroke:#000000;#fill:#00ff00;" y="50">sometext</text> 
    <rect x="0.65234375" fill="rgba(0,0,0,0)" width="55.621094" stroke-width="1" stroke="#ff0000" height="8.597656" y="8.425781"/> 
</svg> 
+0

Puoi anche inserire il codice che aggiunge il rettangolo? –

+0

il rettangolo che aggiunge il codice si trova all'interno del ciclo for, subito dopo l'avvio del documento. Non sono sicuro se questo è il modo giusto per farlo. –

+0

Nevermind, non ho fatto scorrere verso il basso abbastanza per vedere il ciclo for ... –

risposta

4

Il problema deriva dal fatto che è necessario utilizzare setAttribute invece di setAttributeNS. I specificati x e y coordinate vengono ignorati in quanto non sono i x e y attributi che Batik aspetta nello spazio dei nomi di default, sembrano essere riconosciuti come altri attributi sconosciuti. Basta usare questo:

txtElem.setAttribute("x", "30"); 
txtElem.setAttribute("y", "50"); 
txtElem.setAttribute("style", "font-family:Arial;font-size:20;stroke:#000000;fill:#00ff00;"); 
4

Prova questa:

rectangle.setAttributeNS(null, 

e lasciare svgNS solo in createElementNS.

+1

Non so perché questa risposta ha ricevuto un downvote. 'setAttributeNS (null, ...)' è anche dichiarato il metodo preferibile (al contrario di 'setAttribute (...)') nelle FAQ ufficiali di Batik: http://xmlgraphics.apache.org/batik/faq.html (vedi domanda 3.4: "Quando creo nuovi elementi SVG o modifichiamo alcuni attributi SVG tramite l'API DOM, da ECMAScript, non succede nulla, le modifiche non sono renderizzate. Perché no?") – ComFreek

Problemi correlati