Source Code Cross Referenced for LineBox.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » css2 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » visualweb.api.designer » org.netbeans.modules.visualweb.css2 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.modules.visualweb.css2;
043:
044:        import java.awt.Color;
045:        import java.awt.Graphics;
046:
047:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition;
048:        import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
049:        import org.netbeans.modules.visualweb.api.designer.cssengine.CssValue;
050:        import org.netbeans.modules.visualweb.designer.WebForm;
051:        import org.netbeans.modules.visualweb.api.designer.cssengine.XhtmlCss;
052:        import org.netbeans.modules.visualweb.designer.CssUtilities;
053:        import org.netbeans.modules.visualweb.designer.DesignerUtils;
054:
055:        import org.openide.ErrorManager;
056:
057:        import org.w3c.dom.Element;
058:        import org.w3c.dom.Node;
059:
060:        /**
061:         * LineBox, used during inline formatting of CSS2 content.
062:         * The LineBox wholds Boxes for a single line.
063:         * <p>
064:         * See  http://www.w3.org/TR/REC-CSS2/visuren.html
065:         *
066:         * @todo Should the line box know its width? Its margins?
067:         *
068:         * NOTE: This class has close ties with the ModelMapper class so be
069:         * sure to keep the two in sync.
070:         *
071:         * @author Tor Norbye
072:         */
073:        public class LineBox extends ContainerBox {
074:            private int maxWidth;
075:            private int nextX;
076:
077:            /** True iff the linebox should be float positioned */
078:            boolean isFloated;
079:
080:            public LineBox(WebForm webform, Element element, int maxWidth,
081:                    int indent) {
082:                // A LineBox isn't exactly an inline box, but it's NOT a block
083:                // level box. Perhaps I should reverse the logic and call
084:                // the constructor parameter "blocklevel" instead.
085:                super (webform, element, BoxType.LINEBOX, true, false);
086:
087:                // XXX why am I passing element to super? I shouldn't do that
088:                this .maxWidth = maxWidth;
089:                this .nextX = indent;
090:
091:                effectiveTopMargin = 0; // Is this still necessary?
092:                effectiveBottomMargin = 0;
093:            }
094:
095:            protected String paramString() {
096:                StringBuffer sb = new StringBuffer();
097:
098:                for (int i = 0; i < getBoxCount(); i++) {
099:                    CssBox child = getBox(i);
100:
101:                    if (child.getBoxType() == BoxType.TEXT) {
102:                        sb.append(((TextBox) child).getText());
103:                    } else if (child.getBoxType() == BoxType.SPACE) {
104:                        sb.append(' ');
105:                    } else if (child.getBoxType() == BoxType.LINEBREAK) {
106:                        sb.append("<br>");
107:                    } else if (child.getElement() != null) {
108:                        sb.append('<');
109:                        sb.append(child.getElement().getTagName());
110:                        sb.append('>');
111:                    }
112:                }
113:
114:                return "floated=" + isFloated + "," + "contents="
115:                        + sb.toString() + "," + // NOI18N
116:                        super .paramString();
117:            }
118:
119:            /** LineBoxes do not have margins, borders, grids, etc. like regular
120:             * boxes.
121:             */
122:            protected void initialize() {
123:                effectiveTopMargin = 0;
124:                effectiveBottomMargin = 0;
125:            }
126:
127:            /** LineBoxes do not have margins, borders, grids, etc. like regular
128:             * boxes.
129:             */
130:            protected void initializeInvariants() {
131:            }
132:
133:            /**
134:             *  Return the maximum/allocated width of this line box.
135:             *  This will typically be the width of the containing block,
136:             *  but floats may reduce the width.
137:             */
138:            public int getMaxWidth() {
139:                return maxWidth;
140:            }
141:
142:            /**
143:             *  Check whether the given box will fit in this line box.
144:             */
145:            public boolean canFit(CssBox box) {
146:
147:                int boxWidth = box.getWidth();
148:
149:                return !((nextX + leftMargin + boxWidth) > maxWidth);
150:            }
151:
152:            /**
153:             *  Check whether the given box will fit in this line box.
154:             * Now counting floats.
155:             */
156:            public boolean canFit(FormatContext context, CssBox box, int targetY) {
157:                if (box.getParent() == null) {
158:                    return (canFit(box));
159:                }
160:                //we need to recalculate the height and the width for a newly added
161:                //inline box, because it may not fit if there is a clear box and
162:                //the inline box height is bigger than the line height. In such a case,
163:                //this line will overlap with the clear box
164:
165:                //a resulting line height would be a maximum of the boxes height
166:                int maxHeight = Math.max(box.getHeight(), box.getHeight());
167:                //need to recalculate the line width
168:                int maxWidth = context.getMaxWidth(this , this .getParent(),
169:                        targetY, maxHeight);
170:
171:                int boxWidth = box.getWidth();
172:
173:                return !((nextX + leftMargin + boxWidth) > maxWidth);
174:            }
175:
176:            /**
177:             *  Return true iff the line box is "full", e.g. it cannot accomodate
178:             *  any more content.
179:             */
180:            public boolean isFull() {
181:                return nextX >= maxWidth;
182:            }
183:
184:            /**
185:             * Return the "real" width of the box. This is the actual width
186:             * of the text/boxes in the line box, as opposed to the allocated
187:             * width.
188:             *
189:             * @todo If text-align is justify, we should return maxWidth since
190:             *  we will fill it out.
191:             */
192:            public int getActualWidth() {
193:                return nextX;
194:            }
195:
196:            /**
197:             * Return the next x position that we will assign to a box
198:             * added to this line box. The caller is responsible for actually
199:             * making sure the box will fit (by calling canFit()) first.
200:             */
201:            public int getNextX() {
202:                return nextX;
203:            }
204:
205:            /**
206:             *  Report whether the line box is empty (contains no inline boxes).
207:             *
208:             *  @return true iff there are no inline boxes in this linebox.
209:             */
210:            public boolean isEmpty() {
211:                return getBoxCount() == 0;
212:            }
213:
214:            /**
215:             * Adjust the horizontal alingment of this line. Shift the
216:             * linebox around in the containing block; this mostly mean moving
217:             * it to the left or right containing block edge, but it also has to
218:             * for account for floats.
219:             * lineHeight must be passed in; we need the line height to
220:             * decide if we intersect any floats. I could just use the box height
221:             * (which will be set after applyVerticalAlignments) but this ensures
222:             * that the caller doesn't accidentally call applyHorizontalAlignments
223:             * before applyVerticalAlignments, etc.
224:             * @todo This method works by moving the entire linebox left/right.
225:             *   That's not right (and wouldn't work for justify). It also
226:             *   conflicts with what is computed in addToLineBox (where we set
227:             *   the position.)   Revisit this.
228:             */
229:            public void applyHorizontalAlignments(int leftEdge, int lineHeight,
230:                    FormatContext context) {
231:                if (isEmpty()) {
232:                    return;
233:                }
234:
235:                // TODO Left edge code is wrong - not taking floats into consideration
236:                //        Value al = null;
237:                CssValue cssAl = null;
238:
239:                Element element = getElement();
240:                if (element != null) {
241:                    //            al = CssLookup.getValue(element, XhtmlCss.TEXT_ALIGN_INDEX);
242:                    cssAl = CssProvider.getEngineService()
243:                            .getComputedValueForElement(element,
244:                                    XhtmlCss.TEXT_ALIGN_INDEX);
245:                } else {
246:                    ErrorManager
247:                            .getDefault()
248:                            .log(
249:                                    "linebox element was null - can't look up an alignment for it");
250:                }
251:
252:                //        if (al != null) {
253:                if (cssAl != null) {
254:                    //            if (al == CssValueConstants.LEFT_VALUE) {
255:                    if (CssProvider.getValueService().isLeftValue(cssAl)) {
256:                        // Done below - fall through
257:                        //            } else if (al.equals(CssValueConstants.RIGHT_VALUE)) {
258:                        // XXX Revise if really equals is needed or it is just a mistake and identity check is OK.
259:                    } else if (CssProvider.getValueService()
260:                            .isRightValue(cssAl)) {
261:                        // XXX No, gotta subtrack rightPadding, rightBorderWidth,
262:                        // and rightPadding!
263:                        int x = /*containingBlockX+*/(leftEdge + containingBlockWidth)
264:                                - getWidth();
265:                        setX(x);
266:
267:                        return;
268:                        //            } else if (al == CssValueConstants.CENTER_VALUE || al == CssValueConstants.RAVECENTER_VALUE) {
269:                    } else if (CssProvider.getValueService().isCenterValue(
270:                            cssAl)
271:                            || CssProvider.getValueService().isRaveCenterValue(
272:                                    cssAl)) {
273:                        // XXX No, gotta subtrack rightPadding, rightBorderWidth,
274:                        // and rightPadding!
275:                        int x = /*containingBlockX*/+leftEdge
276:                                + ((containingBlockWidth - getWidth()) / 2);
277:                        setX(x);
278:
279:                        return;
280:                        //            } else if (al == CssValueConstants.JUSTIFY_VALUE) {
281:                    } else if (CssProvider.getValueService().isJustifyValue(
282:                            cssAl)) {
283:                        // "Conforming user agents may interpret the value
284:                        // 'justify' as 'left' or 'right', depending on
285:                        // whether the element's default writing direction is
286:                        // left-to-right or right-to-left, respectively. "
287:                        // Ah heck, it's easy so let's do it (not doing
288:                        // character spacing, just word spacing)
289:                        int n = getBoxCount();
290:                        setX(0);
291:
292:                        if (n > 1) {
293:                            int textWidth = 0;
294:
295:                            for (int i = 0; i < n; i++) {
296:                                textWidth += getBox(i).getWidth(); // contentWidth instead?
297:                            }
298:
299:                            int space = maxWidth - textWidth;
300:
301:                            if (space < textWidth) { // don't justify nearly empty lines
302:
303:                                int portion = space / (n - 1); // separator
304:                                int x = 0;
305:
306:                                for (int i = 0; i < (n - 1); i++) {
307:                                    CssBox box = getBox(i);
308:                                    box.setX(x);
309:                                    x += box.getWidth();
310:                                    x += portion;
311:                                }
312:
313:                                CssBox lastBox = getBox(n - 1);
314:                                lastBox.setX(maxWidth - lastBox.getWidth());
315:                            }
316:                        }
317:                    } else {
318:                        //                assert false : al;
319:                        ErrorManager.getDefault().notify(
320:                                ErrorManager.INFORMATIONAL,
321:                                new IllegalStateException(
322:                                        "Unexpected alignment value, cssAl="
323:                                                + cssAl)); // NOI18N
324:                    }
325:                }
326:
327:                // Left alignment: only need to adjust for floats
328:                setX(leftEdge); // XXX What about containingBlockX?
329:            }
330:
331:            /**
332:             *  For each of the inline boxes on this line, adjust
333:             *  the vertical position of the inline boxes according
334:             *  to the individual vertical alignment settings.
335:             *  <p
336:             *  @todo Implement proper alignment fixing using font alignments
337:             *        etc.
338:             *  @return the total height of the line. If the LineBox is
339:             *          empty, it will return -1.
340:             */
341:            public int applyVerticalAlignments() {
342:                /*
343:                if (isEmpty()) {
344:                    return -1;
345:                }
346:                 */
347:                int height = 0;
348:
349:                // The above is the MINIMUM line height - however, the spec
350:                // (section 10.8.1) actually states that it's the minimum line
351:                // height when set on a block-level element; if it's set on an
352:                // inline element, it's the exact height of each box generated
353:                // by the element (except for inline replaced element, where
354:                // the box height is given by the height property.)
355:                // This gets a bit tricky since the attribute is inherited.
356:                int num = getBoxCount();
357:                int maxAbove = 0; // above baseline
358:                int maxBelow = 0; // below baseline
359:                boolean haveText = false;
360:
361:                for (int i = 0; i < num; i++) {
362:                    // XXX This needs to get better - gotta use font
363:                    // alignment, images, etc.
364:                    CssBox box = getBox(i);
365:                    int h;
366:                    //10.8
367:                    //On an inline-level element, 'line-height' specifies the height
368:                    //that is used in the calculation of the line box height (except for
369:                    //inline replaced elements, where the height of the box is given
370:                    //by the 'height' property).
371:                    CssValue cssBoxHeightValue = CssProvider.getEngineService()
372:                            .getComputedValueForElement(box.getElement(),
373:                                    XhtmlCss.LINE_HEIGHT_INDEX);
374:                    if (!box.isReplacedBox()
375:                            && !CssProvider.getValueService().isNormalValue(
376:                                    cssBoxHeightValue)
377:                            // XXX #6494312 Faking support for inline tables.
378:                            && !(box instanceof  TableBox)) {
379:                        h = (int) cssBoxHeightValue.getFloatValue();
380:                    } else {
381:                        h = box.getHeight();
382:                        if (box.getBoxType() == BoxType.TEXT) {
383:                            haveText = true;
384:                        }
385:
386:                    }
387:
388:                    int above = box.getContributingBaseline();
389:                    int below = h - above;
390:
391:                    // Boxes that have no baseline, such as images, also don't force themselves
392:                    // below the baseline
393:                    if (above == 0) {
394:                        below = 0;
395:                    }
396:
397:                    if (above > maxAbove) {
398:                        maxAbove = above;
399:                    }
400:
401:                    if (below > maxBelow) {
402:                        maxBelow = below;
403:                    }
404:
405:                    if (!box.isReplacedBox()
406:                            && !CssProvider.getValueService().isNormalValue(
407:                                    cssBoxHeightValue)
408:                            // XXX #6494312 Faking support for inline tables.
409:                            && !(box instanceof  TableBox)) {
410:                    } else {
411:                        if (maxAbove + maxBelow > h) {
412:                            h = maxAbove + maxBelow;
413:                        }
414:                    }
415:
416:                    //if the box belongs to some nested container, need to take the line-height 
417:                    //property from that container (in case it has it)
418:                    CssBox inlineParent = box;
419:                    while ((inlineParent = inlineParent.originalInlineContainer) != null) {
420:                        cssBoxHeightValue = CssProvider.getEngineService()
421:                                .getComputedValueForElement(
422:                                        inlineParent.getElement(),
423:                                        XhtmlCss.LINE_HEIGHT_INDEX);
424:                        if (!CssProvider.getValueService().isNormalValue(
425:                                cssBoxHeightValue)
426:                                && !CssProvider.getEngineService()
427:                                        .isInheritedStyleValueForElement(
428:                                                inlineParent.getElement(),
429:                                                XhtmlCss.LINE_HEIGHT_INDEX)) {
430:                            //height of the line is exactly the value
431:                            h = (int) cssBoxHeightValue.getFloatValue();
432:                            break;
433:                        }
434:                    }
435:                    if (height < h) {
436:                        height = h;
437:                    }
438:                }
439:
440:                Element element = getElement();
441:                if (haveText) {
442:                    if (element != null) { // XXX This is wrong - I should use the element of the child that had text
443:                        // If not, try setting body font size to 48pt, and have a single <span> with font size 8pt. 
444:                        // The linebox containing the span should have height 8 not 48!
445:                        //                Value heightValue = CssLookup.getValue(element, XhtmlCss.LINE_HEIGHT_INDEX);
446:                        CssValue cssHeightValue = CssProvider
447:                                .getEngineService().getComputedValueForElement(
448:                                        element, XhtmlCss.LINE_HEIGHT_INDEX);
449:
450:                        //                if (heightValue != CssValueConstants.NORMAL_VALUE) {
451:                        if (!CssProvider.getValueService().isNormalValue(
452:                                cssHeightValue)) {
453:                            //                    int lineHeight = (int)heightValue.getFloatValue();
454:                            int lineHeight = (int) cssHeightValue
455:                                    .getFloatValue();
456:                            if (lineHeight > height) {
457:                                height = lineHeight;
458:                            }
459:                        }
460:                    }
461:                }
462:
463:                // linebox's baseline. This is the "baseline of the parent box"
464:                // listed in the CSS2 spec under the vertical-align property.
465:                //        int baseLine = height - maxBelow;
466:                // XXX #109310 The baseline is at the bottom.
467:                int baseLine = height;
468:
469:                // TODO: implement half-leading!! See CSS2 section 10.8.1!
470:                // Vertical alignment:
471:                // TODO: implement correct text-top, text-bottom and middle
472:                // semantics, plus properly compute offset to be used in sub
473:                // and super alignment
474:                for (int i = 0; i < num; i++) {
475:                    // XXX This needs to get better - gotta use font
476:                    // alignment, images, etc.
477:                    CssBox box = getBox(i); // XX do nothing for LINEBREAK!!!
478:                    //            Value align = CssLookup.getValue(box.getElement(), XhtmlCss.VERTICAL_ALIGN_INDEX);
479:                    CssValue cssAlign;
480:                    if (box.originalInlineContainer != null
481:                            && !CssProvider.getEngineService()
482:                                    .isInheritedStyleValueForElement(
483:                                            box.getElement(),
484:                                            XhtmlCss.VERTICAL_ALIGN_INDEX)) {
485:                        cssAlign = CssProvider.getEngineService()
486:                                .getComputedValueForElement(
487:                                        box.originalInlineContainer
488:                                                .getElement(),
489:                                        XhtmlCss.VERTICAL_ALIGN_INDEX);
490:                    } else {
491:                        cssAlign = CssProvider.getEngineService()
492:                                .getComputedValueForElement(box.getElement(),
493:                                        XhtmlCss.VERTICAL_ALIGN_INDEX);
494:                    }
495:                    //            if (align == CssValueConstants.BASELINE_VALUE) {
496:                    if (CssProvider.getValueService().isBaseLineValue(cssAlign)) {
497:                        // XXX Just have a metrics accessor on CssBox instead and use that?
498:                        int y = baseLine - box.getBaseline();
499:                        box.setY(y);
500:                        //            } else if ((align == CssValueConstants.SUPER_VALUE) ||
501:                        //                    (align == CssValueConstants.SUB_VALUE)) {
502:                    } else if (CssProvider.getValueService().isSuperValue(
503:                            cssAlign)
504:                            || CssProvider.getValueService().isSubValue(
505:                                    cssAlign)) {
506:                        int SHIFT;
507:
508:                        // TODO -- gotta compute from font size! But which font? linebox'!
509:                        //                if (align == CssValueConstants.SUPER_VALUE) {
510:                        if (CssProvider.getValueService()
511:                                .isSuperValue(cssAlign)) {
512:                            SHIFT = -3;
513:                        } else {
514:                            SHIFT = 3;
515:                        }
516:
517:                        int y = baseLine - box.getBaseline() + SHIFT;
518:                        box.setY(y);
519:                        //            } else if ((align == CssValueConstants.TOP_VALUE) ||
520:                        //                    (align == CssValueConstants.TEXT_TOP_VALUE)) {
521:                    } else if (CssProvider.getValueService().isTopValue(
522:                            cssAlign)
523:                            || CssProvider.getValueService().isTextTopValue(
524:                                    cssAlign)) {
525:                        // This implements top, not text-top so add separate computation
526:                        // for that
527:                        box.setY(0);
528:                        //            } else if ((align == CssValueConstants.BOTTOM_VALUE) ||
529:                        //                    (align == CssValueConstants.TEXT_BOTTOM_VALUE)) {
530:                    } else if (CssProvider.getValueService().isBottomValue(
531:                            cssAlign)
532:                            || CssProvider.getValueService().isTextBottomValue(
533:                                    cssAlign)) {
534:                        // This implements bottom, not text-bottom so add separate
535:                        // computation for that
536:                        box.setY(height - box.getHeight());
537:                        //            } else if (align == CssValueConstants.MIDDLE_VALUE) {
538:                    } else if (CssProvider.getValueService().isMiddleValue(
539:                            cssAlign)) {
540:                        // How do we compute the parent x-height called for in
541:                        // the spec?  Hack for now -- just use half of
542:                        // parent's fontheight!  Looks like Batik's
543:                        // LengthManager is doing a 0.5 factor of the font
544:                        // height to compute EXS anyway!
545:
546:                        if (isTextualBox(box)) {
547:                            //                    int pex = (int)CssLookup.getFontSize(element, DesignerSetings.getInstance().getDefaultFontSize()) / 2;
548:                            //                    int pex = (int)CssProvider.getValueService().getFontSizeForElement(element, DesignerSettings.getInstance().getDefaultFontSize()) / 2;
549:                            int pex = (int) CssProvider.getValueService()
550:                                    .getFontSizeForElement(element,
551:                                            webform.getDefaultFontSize()) / 2;
552:                            int y = baseLine - (box.getHeight() / 2) - pex;
553:                            box.setY(y);
554:                        } else {
555:                            // XXX #122162 It seems it doesn't work for all non-textual boxes.
556:                            ////                     XXX #6344561 The computation didn't work for images, only for text.
557:                            ////                     TODO How it should be done correct way, study the spec (CSS2 10.8.1).
558:                            int y = (baseLine / 2) - (box.getHeight() / 2);
559:                            box.setY(y);
560:                        }
561:                    } else {
562:                        // Percentage or length -- not yet handled!
563:
564:                        /*
565:                            // If percentage: from http://www.westciv.com/style_master/academy/css_tutorial/properties/text_layout.html
566:                        "Percentage values
567:
568:                        Specifying vertical-align as a percentage value gives rise to a quite complicated situation. The baseline of the element is raised above the baseline of its parent element. By how much? By that percentage of the element's line-height.
569:
570:                        For example, {vertical-align: 20%} with an element that has a line-height of 10pt, the baseline of the element will be raised 2 points above the baseline of its parent element.
571:
572:                        You can lower the baseline of an element below the baseline of its parent by using negative percentage values."
573:                         */
574:
575:                        // XXX This nasty assertion always breaks the designer, revise what is supposed to be here.
576:                        //                assert false : align;
577:                        // XXX #109310 This should be lenght value now (what to do with percentage?).
578:                        // For now handle similar way like a baseline.
579:                        int absoluteAlign = (int) cssAlign.getFloatValue();
580:                        int newY = baseLine - box.getBaseline() - absoluteAlign;
581:                        box.setY(newY);
582:                    }
583:                }
584:
585:                if (height == 0) {
586:                    // We've added a space but not text - return default line height
587:                    if (element != null) {
588:                        //                Value heightValue = CssLookup.getValue(element, XhtmlCss.LINE_HEIGHT_INDEX);
589:                        CssValue cssHeightValue = CssProvider
590:                                .getEngineService().getComputedValueForElement(
591:                                        element, XhtmlCss.LINE_HEIGHT_INDEX);
592:
593:                        //                if (heightValue == CssValueConstants.NORMAL_VALUE) {
594:                        if (CssProvider.getValueService().isNormalValue(
595:                                cssHeightValue)) {
596:                            //                    height = (int)(1.1 * CssLookup.getFontSize(element, DesignerSettings.getInstance().getDefaultFontSize()));
597:                            //                    height = (int)(1.1 * CssProvider.getValueService().getFontSizeForElement(element, DesignerSettings.getInstance().getDefaultFontSize()));
598:                            height = (int) (1.1 * CssProvider.getValueService()
599:                                    .getFontSizeForElement(element,
600:                                            webform.getDefaultFontSize()));
601:                        } else {
602:                            //                    height = (int)heightValue.getFloatValue();
603:                            height = (int) cssHeightValue.getFloatValue();
604:                        }
605:                    }
606:                }
607:
608:                return height;
609:            }
610:
611:            private static boolean isTextualBox(CssBox box) {
612:                if (box == null) {
613:                    return false;
614:                }
615:                BoxType boxType = box.getBoxType();
616:                return boxType == BoxType.TEXT || boxType == BoxType.SPACE
617:                        || boxType == BoxType.LINEBREAK;
618:            }
619:
620:            protected void paintBackground(Graphics g, int px, int py) {
621:                // super.paint(g); // We don't want backgrounds painted, etc.
622:                // XXX pass in Rectangle directly since that's what we always want?
623:                if (isEmpty()) {
624:                    return;
625:                }
626:
627:                px += getX();
628:                py += getY();
629:
630:                int num = getBoxCount();
631:
632:                for (int i = 0; i < num; i++) {
633:                    CssBox ilb = getBox(i);
634:
635:                    if (ilb.getBoxType() == BoxType.LINEBREAK) {
636:                        assert i == (num - 1);
637:
638:                        return;
639:                    }
640:
641:                    CssBox positionParent = ilb.getPositionedBy();
642:
643:                    if (positionParent != this ) { // XXX Can this happen in a linebox???
644:
645:                        // Not positioned by us - need to compute the
646:                        // positioning parent's absolute position
647:                        ilb.paintBackground(g, positionParent.getAbsoluteX(),
648:                                positionParent.getAbsoluteY());
649:                    } else {
650:                        ilb.paintBackground(g, px, py);
651:                    }
652:                }
653:            }
654:
655:            public void paint(Graphics g, int px, int py) {
656:                // super.paint(g); // We don't want backgrounds painted, etc.
657:                // XXX pass in Rectangle directly since that's what we always want?
658:                if (isEmpty()) {
659:                    return;
660:                }
661:
662:                px += getX();
663:                py += getY();
664:
665:                int num = getBoxCount();
666:
667:                for (int i = 0; i < num; i++) {
668:                    CssBox ilb = getBox(i);
669:
670:                    if (ilb.getBoxType() == BoxType.LINEBREAK) {
671:                        assert i == (num - 1);
672:
673:                        if (!CssBox.paintSpaces) {
674:                            continue;
675:                        }
676:                    }
677:
678:                    CssBox positionParent = ilb.getPositionedBy();
679:
680:                    if (positionParent != this ) {
681:                        // Not positioned by us - need to compute the
682:                        // positioning parent's absolute position
683:                        ilb.paint(g, positionParent.getAbsoluteX(),
684:                                positionParent.getAbsoluteY());
685:                    } else {
686:                        ilb.paint(g, px, py);
687:                    }
688:                }
689:
690:                if (CssBox.paintSpaces) {
691:                    g.setColor(Color.PINK);
692:                    g.drawRect(getAbsoluteX(), getAbsoluteY(),
693:                            (width == 0) ? 10 : width, height);
694:                }
695:            }
696:
697:            protected void addBox(CssBox box, CssBox prevBox, CssBox nextBox) {
698:                assert box.isInlineBox();
699:
700:                // Suppress repeated LineBox.SPACE's.
701:                // XXX is this taken care of by the LineBoxGroup?
702:                if ((box.getBoxType() == BoxType.SPACE)
703:                        && (getBoxCount() > 0)
704:                        && (getBox(getBoxCount() - 1).getBoxType() == BoxType.SPACE)) {
705:                    return;
706:                }
707:
708:                //super.addBox(box, prevBox, nextBox);
709:                // Don't do a super.addBox because we want this list to be
710:                // "anonymous"; the fact that boxes are parented by the linebox
711:                // is not known to them - so don't set parent pointers, and don't
712:                // maintain parent indices (BoxList.syncParentIndices)
713:                if (boxes == null) {
714:                    int initialSize = 25;
715:
716:                    // XXX todo: pick an initial size based on the box we're
717:                    // about to create; e.g. look at our node/element field,
718:                    // look at the number of children, and do something based
719:                    // on that. Typically we should do the number of element
720:                    // nodes in the child (since most text nodes are just
721:                    // whitespace formatting), but for LineBoxes we should do
722:                    // something smarter.
723:                    boxes = new BoxList(initialSize);
724:                    boxes.setSyncParentIndices(false);
725:
726:                    if (boxType != BoxType.LINEBOX) {
727:                        boxes.setKeepSorted(true);
728:                    }
729:                }
730:
731:                // This seems to be not needed yet.
732:                //        // XXX #113899 Ensure the correct order. Due to complicated architecture,
733:                //        // strange layout processing of LineBoxGroup sometimes leads to wrong order in the line box.
734:                //        int size = boxes.size();
735:                //        if (size > 0 && prevBox == null && nextBox == null) {
736:                //            for (int i = 0; i < size; i++) {
737:                //                CssBox sibling = boxes.get(i);
738:                //                if(DesignerUtils.getNextSiblingElement(box.getElement()) == sibling.getElement()) {
739:                //                    nextBox = sibling;
740:                //                    break;
741:                //                }
742:                //            }
743:                //            for (int i = size - 1; i >= 0; i--) {
744:                //                CssBox sibling = boxes.get(i);
745:                //                if (DesignerUtils.getPreviousSiblingElement(box.getElement()) == sibling.getElement()) {
746:                //                    prevBox = sibling;
747:                //                    break;
748:                //                }
749:                //            }
750:                //        }
751:
752:                boxes.add(box, prevBox, nextBox);
753:
754:                //box.setParent(this);
755:                box.setPositionedBy(this ); // ????
756:
757:                box.setLocation(nextX, 0);
758:                nextX += box.getWidth() + box.leftMargin + box.rightMargin;
759:            }
760:
761:            public void relayout(FormatContext context) {
762:                // LineBoxGroup should never delegate layout to us but let's
763:                // make doubly sure since inheriting ContainerBox.relayout
764:                // would be Bad.
765:                throw new RuntimeException();
766:            }
767:
768:            void computeHorizontalLengths(FormatContext context) {
769:                // LineBoxes are anonymous, so they should have no "auto" settings
770:                // on them
771:            }
772:
773:            void computeVerticalLengths(FormatContext context) {
774:                // LineBoxes are anonymous, so they should have no "auto" settings
775:                // on them
776:            }
777:
778:            /** Return a position within this line box that the given x coordinate
779:             * points to in the document.
780:             */
781:            //    public Position computePosition(int px) {
782:            public DomPosition computePosition(int px) {
783:                if (getBoxCount() > 0) {
784:                    // Ensure that we're not pointing to a position further out on
785:                    // the line than the last box
786:                    CssBox last = getBox(getBoxCount() - 1);
787:                    int rightmost = (last.getX() + last.getWidth()) - 1;
788:
789:                    if (rightmost < px) {
790:                        px = rightmost;
791:                    }
792:                }
793:
794:                for (int i = 0, n = getBoxCount(); i < n; i++) {
795:                    CssBox box = getBox(i);
796:
797:                    if (box.getBoxType() == BoxType.LINEBREAK) {
798:                        //                Position pos = Position.create(box.getSourceElement(), false);
799:                        DomPosition pos = webform.createDomPosition(box
800:                                .getSourceElement(), false);
801:
802:                        //                if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
803:                        //                if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
804:                        if (ModelViewMapper.isValidPosition(webform, pos,
805:                                false, /*webform*/webform.getManager()
806:                                        .getInlineEditor())) {
807:                            return pos;
808:                        }
809:                    }
810:
811:                    // TODO -- reformat
812:                    int left = box.getX();
813:                    int right = left + box.getWidth();
814:
815:                    if (left > px) {
816:                        // We've already passed the spot: it must be over a space
817:                        // between this inline box and the previous inline box
818:                        // See which one is closest
819:                        CssBox closest = null;
820:                        boolean after = false;
821:
822:                        if (i > 0) {
823:                            int currDistance = left - px;
824:                            CssBox prevBox = getBox(i - 1);
825:                            int prevDistance = px
826:                                    - (prevBox.getX() + prevBox.getWidth());
827:
828:                            if (currDistance <= prevDistance) {
829:                                closest = box;
830:                            } else {
831:                                closest = prevBox;
832:                                after = true;
833:                            }
834:                        } else {
835:                            // No previous box - so this is definitely closest
836:                            closest = box;
837:                        }
838:
839:                        if (closest.getBoxType() == BoxType.TEXT) {
840:                            // Text boxes: we support positions (offsets)
841:                            // within the text
842:                            TextBox tb = (TextBox) closest;
843:                            //                    Position pos = tb.getFirstPosition();
844:                            DomPosition pos = tb.getFirstPosition();
845:
846:                            //                    if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
847:                            //                    if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
848:                            if (ModelViewMapper.isValidPosition(webform, pos,
849:                                    false, /*webform*/webform.getManager()
850:                                            .getInlineEditor())) {
851:                                return pos;
852:                            }
853:                        } else if (closest.getBoxType() == BoxType.SPACE) {
854:                            // Space boxes: we support positions (offsets)
855:                            // within the text
856:                            SpaceBox tb = (SpaceBox) closest;
857:                            //                    Position pos = tb.getFirstPosition();
858:                            DomPosition pos = tb.getFirstPosition();
859:
860:                            //                    if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
861:                            //                    if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
862:                            if (ModelViewMapper.isValidPosition(webform, pos,
863:                                    false, /*webform*/webform.getManager()
864:                                            .getInlineEditor())) {
865:                                return pos;
866:                            }
867:                        } else {
868:                            //                    Position pos = Position.create(closest.getSourceElement(), after);
869:                            DomPosition pos = webform.createDomPosition(closest
870:                                    .getSourceElement(), after);
871:
872:                            //                    if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
873:                            //                    if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
874:                            if (ModelViewMapper.isValidPosition(webform, pos,
875:                                    false, /*webform*/webform.getManager()
876:                                            .getInlineEditor())) {
877:                                return pos;
878:                            }
879:                        }
880:                    } else if ((px >= left) && (px <= right)) {
881:                        if (box.getBoxType() == BoxType.TEXT) {
882:                            // Text boxes: we support positions (offsets)
883:                            // within the text
884:                            //                    Position pos = ((TextBox)box).computePosition(px - left);
885:                            DomPosition pos = ((TextBox) box)
886:                                    .computePosition(px - left);
887:
888:                            //                    if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
889:                            //                    if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
890:                            if (ModelViewMapper.isValidPosition(webform, pos,
891:                                    false, /*webform*/webform.getManager()
892:                                            .getInlineEditor())) {
893:                                return pos;
894:                            }
895:                        } else if (box.getBoxType() == BoxType.SPACE) {
896:                            // Text boxes: we support positions (offsets)
897:                            // within the text
898:                            //                    Position pos = ((SpaceBox)box).computePosition(px - left);
899:                            DomPosition pos = ((SpaceBox) box)
900:                                    .computePosition(px - left);
901:
902:                            //                    if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
903:                            //                    if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
904:                            if (ModelViewMapper.isValidPosition(webform, pos,
905:                                    false, /*webform*/webform.getManager()
906:                                            .getInlineEditor())) {
907:                                return pos;
908:                            }
909:
910:                            /*
911:                            } else if (DesignerUtils.isCaretTarget(box)) {
912:                            // It's an "atomic" unit; place the caret
913:                            // on the outside
914:                            } else if (box instanceof FormComponentBox) {
915:                            Position pos = ((FormComponentBox)box).computePosition(x-box.getAbsoluteX());
916:                            if (pos != null) {
917:                                Position pos = pos;
918:                                if (Utilities.checkPosition(pos, false, webformwebform.getManager().getInlineEditor()) != Position.NONE) {
919:                                    return pos;
920:                                }
921:                            }
922:                             */
923:                        }
924:
925:                        // Other boxes (iframes, images, etc.): the offset
926:                        // is either "before" or "after" the element:
927:                        // offset 0 or 1. We round the x to the nearest
928:                        // left or right edge to decide which side it goes
929:                        // on.
930:                        boolean after = px > ((left + right) / 2);
931:                        //                Position pos = Position.create(box.getSourceElement(), after);
932:                        DomPosition pos = webform.createDomPosition(box
933:                                .getSourceElement(), after);
934:
935:                        //                if (DesignerUtils.checkPosition(pos, false, /*webform*/webform.getManager().getInlineEditor()) != Position.NONE) {
936:                        //                if (ModelViewMapper.isValidPosition(pos, false, /*webform*/webform.getManager().getInlineEditor())) {
937:                        if (ModelViewMapper.isValidPosition(webform, pos,
938:                                false, /*webform*/webform.getManager()
939:                                        .getInlineEditor())) {
940:                            return pos;
941:                        }
942:                    }
943:                }
944:
945:                //        return Position.NONE; // happens when we have no place to put the caret -- all JSF elements
946:                return DomPosition.NONE; // happens when we have no place to put the caret -- all JSF elements
947:            }
948:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.