Changeset 914


Ignore:
Timestamp:
05/12/14 09:28:44 (10 years ago)
Author:
davidb
Message:

Implicit Boxing

Location:
trunk/src/org/expeditee
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/io/DefaultTreeWriter.java

    r460 r914  
    88import org.expeditee.gui.FrameIO;
    99import org.expeditee.gui.MessageBay;
     10import org.expeditee.io.flowlayout.XGroupItem;
    1011import org.expeditee.items.Item;
    1112import org.expeditee.items.Text;
     
    7475       
    7576        protected void outputTree(Frame toWrite) throws IOException {
    76                 if (toWrite == null)
     77                if (toWrite == null) {
    7778                        return;
    78 
     79                }
     80               
     81                XGroupItem.doImplicitBoxing = false;
     82               
    7983                _frames.push(new FrameCounter(toWrite.getName(), -1));
    8084
  • trunk/src/org/expeditee/io/JavaWriter.java

    r478 r914  
    6767                List<Item> y_ordered_items = frame.getItems();
    6868               
     69                for (Item item: y_ordered_items) {
     70                        if (item instanceof Text) {
     71                                Text text_item = (Text)item;
     72                                if (text_item.getText().equalsIgnoreCase("@doImplicitBoxing")) {
     73                                        XGroupItem.doImplicitBoxing = true;
     74                                }
     75                        }
     76                }
    6977                XGroupItem toplevel_xgroup = new XGroupItem(frame,y_ordered_items);
    7078               
  • trunk/src/org/expeditee/io/flowlayout/XGroupItem.java

    r912 r914  
    2323{
    2424        enum FlowType { in_flow, out_of_flow_original, out_of_flow_faked_position };
     25       
     26        public static boolean doImplicitBoxing = true;
    2527       
    2628        class MultiArrowHeadComparable implements Comparator<Item>{
     
    763765        }
    764766       
     767        protected int autocropToTop(XItem xitem)
     768        {
     769                // top-edge over-spill can occur (and is acceptable) when (for example) the given xitem is a raw-text item
     770                // that doesn't neatly fit in an enclosed area (i,e., is poking out the top of an enclosing rectangle) 
     771                // => cut down to the top of 'this' xgroupitem
     772               
     773                int yt = xitem.getBoundingYTop();
     774                               
     775               
     776                yt = cropToTop(yt); // Only changes yt if in an over-spill situation
     777               
     778                return yt;
     779               
     780        }
     781       
     782        protected int autocropToBot(XItem xitem)
     783        {
     784               
     785                // similar to autocropToTop(), bottom-edge over-spill can occur (and is acceptable) with
     786                // a less than precise placed raw-text item
     787               
     788                int yb = xitem.getBoundingYBot();
     789               
     790                yb = cropToBot(yb); // Only changes yb if in an over-spill situation
     791               
     792                return yb;
     793        }
     794       
     795        protected boolean yExtentIntersection(XGroupItem xgroup_item1, XGroupItem xgroup_item2)
     796        {
     797                // Computation applied to y-extent of each rectangle
     798               
     799                // To intersect, either a point in item1 falls inside item2,
     800                // or else item2 is completely within item1
     801               
     802       
     803                int yt1 = xgroup_item1.getBoundingYTop();
     804                int yb1 = xgroup_item1.getBoundingYBot();
     805               
     806                int yt2 = xgroup_item2.getBoundingYTop();
     807               
     808                // yt1 insides item2?
     809                if (xgroup_item2.containedInYExtent(yt1)) {
     810                        return true;
     811                }
     812               
     813                // yb1 inside item2?
     814                if (xgroup_item2.containedInYExtent(yb1)) {
     815                        return true;
     816                }
     817               
     818                // item2 completely inside item1?
     819                //
     820                // With the previous testing, this can be determined
     821                // by checking only one of the values is inside.
     822                // Doesn't matter which => choose yt2
     823               
     824                if (xgroup_item1.containedInYExtent(yt2)) {
     825                        return true;
     826                }
     827               
     828                // Get to here if there is no intersection
     829                return false;
     830               
     831        }
     832        protected ArrayList<XGroupItem> calcXGroupYExtentIntersection(XGroupItem xgroup_pivot_item, List<XGroupItem> xgroup_item_list)
     833        {
     834                ArrayList<XGroupItem> intersect_list = new ArrayList<XGroupItem>();
     835               
     836                for (XGroupItem xgroup_item: xgroup_item_list) {
     837
     838                        if (xgroup_item == xgroup_pivot_item) {
     839                                // Don't bother working out the intersection with itself!
     840                                continue;
     841                        }
     842
     843                        if (yExtentIntersection(xgroup_pivot_item,xgroup_item)) {
     844                                intersect_list.add(xgroup_item);
     845                        }
     846                }
     847       
     848                return intersect_list;
     849        }
     850       
     851        protected ArrayList<YOverlappingItemsTopEdge> calcYSpanOverlap(XItem xitem)
     852        {
     853                int yt = autocropToTop(xitem);
     854                int yb = autocropToBot(xitem);
     855               
     856               
     857                ArrayList<YOverlappingItemsTopEdge> top_edge_list = new ArrayList<YOverlappingItemsTopEdge>();
     858               
     859                for (int y=yt; y<=yb; y++) {
     860
     861                        YOverlappingItemsSpan item_span = getYOverlappingItemsSpan(y);
     862
     863                        if (item_span != null) {
     864
     865                                if (item_span instanceof YOverlappingItemsTopEdge) {
     866
     867                                        YOverlappingItemsTopEdge y_item_span_top_edge = (YOverlappingItemsTopEdge)item_span;
     868                                       
     869                                        top_edge_list.add(y_item_span_top_edge);
     870                                }
     871                        }
     872
     873                }
     874               
     875                return top_edge_list;
     876        }
     877       
     878       
     879        protected boolean multipleYSpanOverlap(XItem xitem)
     880        {
     881                return calcYSpanOverlap(xitem).size() > 0;
     882        }
     883       
    765884        public void mapInItem(XItem xitem)
    766885        {
    767886               
     887                int yt = autocropToTop(xitem);
     888                int yb = autocropToBot(xitem);
     889                /*
    768890                int yt = xitem.getBoundingYTop();
    769891                int yb = xitem.getBoundingYBot();
     
    775897                // similarly, bottom-edge over-spill can occur (and is acceptable) with a less than precise placed raw-text item
    776898                yb = cropToBot(yb); // Only changes yb if in an over-spill situation
    777                        
     899                        */
     900               
    778901                // Merge into 'items_span' checking for overlaps (based on xitem's y-span)
    779902                               
     
    871994        }
    872995       
     996        private ArrayList<DimensionExtent> calcXGroupXGaps(XGroupItem xgroup_pivot_item, List<XGroupItem> xgroup_item_list)
     997        {
     998                // 'xgroup_pivot_item' current not used!!
     999               
     1000                int enclosing_xl = getBoundingXLeft();
     1001                int enclosing_xr = getBoundingXRight();
     1002               
     1003                int enclosing_x_dim = enclosing_xr - enclosing_xl +1;
     1004                boolean is_x_shadow[] = new boolean[enclosing_x_dim]; // defaults all values to false
     1005               
     1006                ArrayList<DimensionExtent> x_gap_list = new ArrayList<DimensionExtent>();
     1007               
     1008                for (XGroupItem xgroup_item: xgroup_item_list) {
     1009                        int xl = xgroup_item.getBoundingXLeft();
     1010                        int xr = xgroup_item.getBoundingXRight();
     1011                       
     1012                        for (int x=xl; x<=xr; x++) {
     1013                                int x_offset = x - enclosing_xl;
     1014                                is_x_shadow[x_offset] = true;
     1015                        }
     1016                }
     1017               
     1018                // New find where the contiguous runs of 'false' are, as they point to the gaps
     1019               
     1020                int x = 1;
     1021                int start_x_gap = enclosing_xl;
     1022                boolean in_gap = true;
     1023               
     1024                while (x < is_x_shadow.length) {
     1025                        boolean prev_is_shadow = is_x_shadow[x-1];
     1026                        boolean this_is_shadow = is_x_shadow[x];
     1027
     1028                        if (prev_is_shadow && !this_is_shadow) {
     1029                                // reached end of shadow, record start of a gap
     1030                                start_x_gap = enclosing_xl + x;
     1031                                in_gap = true;
     1032                        }
     1033                        else if (!prev_is_shadow && this_is_shadow) {
     1034                                // reached the end of a gap, record it
     1035                                int end_x_gap = enclosing_xl + x -1;
     1036                                DimensionExtent de = new DimensionExtent(start_x_gap,end_x_gap);
     1037                                x_gap_list.add(de);
     1038                                in_gap = false;
     1039                        }
     1040                        x++;
     1041                }
     1042               
     1043                if (in_gap) {
     1044                        int end_x_gap = enclosing_xl + x -1;
     1045                        DimensionExtent de = new DimensionExtent(start_x_gap,end_x_gap);
     1046                        x_gap_list.add(de);
     1047                }
     1048               
     1049                return x_gap_list;
     1050        }
     1051
     1052        protected void boxMultipleXRawItemsInGaps(XGroupItem xgroup_pivot_item, ArrayList<DimensionExtent> x_text_gap_list)
     1053        {
     1054                ArrayList<YOverlappingItemsTopEdge> y_span_overlap = calcYSpanOverlap(xgroup_pivot_item);
     1055               
     1056                // work out where continuous runs of raw-text items intersect with the gaps occurring between boxed items
     1057               
     1058                // foreach x-gap,
     1059                //    foreach y-span's list of x-sorted objects,
     1060                //      => see how many raw-text items fit into it
     1061               
     1062               
     1063                ArrayList<ArrayList<XRawItem>> implicit_box_list = new ArrayList<ArrayList<XRawItem>>();
     1064               
     1065                for (DimensionExtent de_gap: x_text_gap_list) {
     1066                       
     1067                        int deg_xl = de_gap.min;
     1068                        int deg_xr = de_gap.max;
     1069                       
     1070                        ArrayList<XRawItem> grouped_raw_text_list = new ArrayList<XRawItem>();
     1071                       
     1072                        int y_span_line_count = 0;
     1073                       
     1074                        for (YOverlappingItemsTopEdge y_top_edge: y_span_overlap) {
     1075                               
     1076                                List<XItem> x_item_list = y_top_edge.x_items.getXItemList();
     1077
     1078                                boolean used_x_raw_text = false;
     1079                               
     1080                                for (XItem x_item: x_item_list) {
     1081                               
     1082                                        if (x_item instanceof XRawItem) {
     1083                                                XRawItem x_raw_item = (XRawItem)x_item;
     1084                                               
     1085                                                int xri_xl = x_raw_item.getBoundingXLeft();
     1086                                                int xri_xr = x_raw_item.getBoundingXRight();
     1087                                               
     1088                                                if ((xri_xl>=deg_xl) && (xri_xr<=deg_xr)) {
     1089                                                        grouped_raw_text_list.add(x_raw_item);
     1090                                                        used_x_raw_text = true;
     1091                                                }
     1092                                        }
     1093                                }
     1094                               
     1095                                if (used_x_raw_text) {
     1096                                        y_span_line_count++;
     1097                                }
     1098                        }
     1099                       
     1100                        // Only interested in implicitly boxing if the formed group is used over 2 or more y-span lines
     1101                        if (y_span_line_count>=2) {
     1102                                implicit_box_list.add(grouped_raw_text_list);
     1103                        }
     1104                }
     1105               
     1106                //System.err.println("*** Number of implicit groups found: " + implicit_box_list.size());
     1107               
     1108                for (ArrayList<XRawItem> implicit_x_item_list : implicit_box_list) {
     1109                       
     1110                        for (YOverlappingItemsTopEdge y_top_edge: y_span_overlap) {
     1111                               
     1112                                List<XItem> yspan_x_item_list = y_top_edge.x_items.getXItemList();
     1113                               
     1114                                // Remove all the XRawItems from the current y-span
     1115                                yspan_x_item_list.removeAll(implicit_x_item_list);
     1116                       
     1117                        }
     1118                       
     1119                        // Create a list of original Text items
     1120                        // (OK that they are not y-ordered)
     1121                        ArrayList<Item> implicit_item_list= new ArrayList<Item>();
     1122                        for (XRawItem x_raw_item: implicit_x_item_list) {
     1123                                Item item = (Text) x_raw_item.item;
     1124                                implicit_item_list.add(item);
     1125                        }
     1126
     1127                        // Now insert them as their own boxed up items
     1128                        XGroupItem implicit_xgroup = new XGroupItem(frame,implicit_item_list);
     1129                        this.mapInItem(implicit_xgroup);
     1130                }
     1131               
     1132        }
     1133       
     1134        protected void implicitBoxing(XGroupItem xgroup_pivot_item,List<XGroupItem> xgroup_item_list) {
     1135               
     1136                // Implicit boxing is needed if there are two or more raw-text items
     1137                // that overlap in y-span-map of the given xgroup_item
     1138               
     1139                // First establish if there is any kind of multiple overlap
     1140                if (multipleYSpanOverlap(xgroup_pivot_item)) {
     1141                       
     1142                        // Overlap could be with other boxed items, so need to investigate further
     1143                       
     1144                        // Do this by working out if there are any raw-text items lurking between the pivot xgroup_item
     1145                        // and the list of other xgroup_items
     1146                       
     1147                        // Step 1: Get list intersection (y-dim) of this group item, with any
     1148                        //         other group items in xgroup_item_list
     1149                        ArrayList<XGroupItem> y_overlapping_xgroup_item_list = calcXGroupYExtentIntersection(xgroup_pivot_item,xgroup_item_list);
     1150                       
     1151                        // Step 2: Work out where the gaps are between the y-overlapping boxes in the x-dimension
     1152                        ArrayList<DimensionExtent> x_text_gap_list = calcXGroupXGaps(xgroup_pivot_item,y_overlapping_xgroup_item_list);
     1153                       
     1154                        // Step 3: Remove any sequences of raw-text items that fall in the gaps from YSpan, box them up, and reinsert
     1155                        boxMultipleXRawItemsInGaps(xgroup_pivot_item,x_text_gap_list);
     1156                       
     1157                }
     1158        }
     1159       
     1160       
     1161
    8731162        public void mapInXGroupItemsRecursive(List<XGroupItem> xgroup_item_list)
    8741163        {
     
    8771166                for (XGroupItem xgroup_item: xgroup_item_list) {
    8781167                        if (!xgroup_item.isOriginalOutOfFlowItem()) {
     1168                               
     1169                                // See if any implicit boxing of raw-text items is needed
     1170                                if (doImplicitBoxing) {
     1171                                        implicitBoxing(xgroup_item,xgroup_item_list);
     1172                                }
    8791173                                mapInItem(xgroup_item); // Map in this x-group-item
    8801174                        }
     
    8921186        }
    8931187       
     1188       
     1189
    8941190        public ArrayList<Item> getYXOverlappingItemList(boolean separateGroups)
    8951191        {
  • trunk/src/org/expeditee/io/flowlayout/XItem.java

    r478 r914  
    4747        }
    4848       
     49        public int getBoundingXRight()
     50        {
     51                return bounding_rect.x + bounding_rect.width -1;
     52        }
     53       
    4954        public int getBoundingWidth()
    5055        {
     
    7681                return bounding_rect.contains(pt);
    7782        }
     83       
     84        public boolean containedInXExtent(int x)
     85        {
     86                int xl = getBoundingXLeft();
     87                int xr = getBoundingXRight();
     88               
     89                return (x>= xl) && (x<=xr);
     90        }
     91       
     92       
     93        public boolean containedInYExtent(int y)
     94        {
     95                int yt = getBoundingYTop();
     96                int yb = getBoundingYBot();
     97               
     98                return (y>= yt) && (y<=yb);
     99        }
     100       
     101       
    78102}
  • trunk/src/org/expeditee/items/Text.java

    r909 r914  
    18751875                                int ldx = 1+getX()+getJustOffset(layout); // Layout draw x
    18761876                               
    1877                                 boolean debug = true;
     1877                                boolean debug = false;
    18781878                                if (debug) {
    18791879                                        g.setColor(new Color(c.getRed(),c.getGreen(),c.getBlue(),40));
Note: See TracChangeset for help on using the changeset viewer.