创建`子表12`

@param {Writer} writer 写对象
@param {Array} segments 分块编码列表
@return {Writer}
968676
function writeSubTable12(writer, segments) {

            writer.writeUint16(12); // format
            writer.writeUint16(0); // reserved
            writer.writeUint32(16 + segments.length * 12); // length
            writer.writeUint32(0); // language
            writer.writeUint32(segments.length); // nGroups

            segments.forEach(function (segment) {
                writer.writeUint32(segment.start);
                writer.writeUint32(segment.end);
                writer.writeUint32(segment.startId);
            });

            return writer;
        }
667270
private Segment createMappedSegment(SegmentDescriptor descriptor) {
    File segmentFile = SegmentFile.createSegmentFile(name, storage.directory(), descriptor.id(), descriptor.version());
    Buffer buffer = MappedBuffer.allocate(segmentFile, Math.min(DEFAULT_BUFFER_SIZE, descriptor.maxSegmentSize()), Integer.MAX_VALUE);
    descriptor.copyTo(buffer);
    Segment segment = new Segment(new SegmentFile(segmentFile), buffer.slice(), descriptor, createIndex(descriptor), new OffsetPredicate(), serializer.clone(), this);
    LOGGER.debug("Created segment: {}", segment);
    return segment;
  }
442019
public static void writeXML(DocumentFragment fragment, Writer writer) throws IOException {
		assert fragment != null : AssertMessages.notNullParameter(0);
		assert writer != null : AssertMessages.notNullParameter(1);
		writeNode(fragment, writer);
	}
374408
function(length, opt) {

            var index = this.segmentIndexAtLength(length, opt);
            if (!index) return null;

            return this.getSegment(index);
        }
89427
def find_write_predecessors(self, address):
        
        # A write operation must be preceded by:
        #   - The "enclosing writer", which is the writer at the address or
        #     the nearest writer higher (closer to the root) in the tree.
        #   - The "enclosing readers", which are the readers at the address
        #     or higher in the tree.
        #   - The "children writers", which include all writers which are
        #     lower in the tree than the address.
        #   - The "children readers", which include all readers which are
        #     lower in the tree than the address.
        #
        # The enclosing writer must be added as it may have modified a node
        # which must not happen after the current write.
        #
        # Writers which are higher in the tree than the enclosing writer may
        # have modified a node at or under the given address.  However, we do
        # not need to include them here as they will have been considered a
        # predecessor to the enclosing writer.
        #
        # Enclosing readers must be included.  Technically, we only need to add
        # enclosing readers which occurred after the enclosing writer, since
        # the readers preceding the writer will have been considered a
        # predecessor of the enclosing writer.  However, with the current
        # data structure we can not determine the difference between readers
        # so we specify them all; this is mostly harmless as it will not change
        # the eventual sort order generated by the scheduler.
        #
        # Children readers must be added, since their reads must happen prior
        # to the write.

        predecessors = set()

        enclosing_writer = None

        node_stream = self._tree.walk(address)

        address_len = len(address)

        # First, walk down from the root to the address, collecting all readers
        # and updating the enclosing_writer if needed.

        try:
            for node_address, node in node_stream:
                if node is not None:
                    predecessors.update(node.readers)

                    if node.writer is not None:
                        enclosing_writer = node.writer

                    if len(node_address) >= address_len:
                        break

        # If the address isn't on the tree, then there aren't any
        # predecessors below the node to worry about (because there
        # isn't anything at all), so return the predecessors that have
        # already been collected.
        except AddressNotInTree as err:
            if err.match is not None:
                return self.find_write_predecessors(err.match)

            return predecessors

        finally:
            if enclosing_writer is not None:
                predecessors.add(enclosing_writer)

        # Next, descend down the tree starting at the address node and
        # find all descendant readers and writers.

        for _, node in node_stream:
            if node is not None:
                if node.writer is not None:
                    predecessors.add(node.writer)

                predecessors.update(node.readers)

        return predecessors
1327523
@JSFunction
    public Object getWriter() {
        if (writer == null)
            return null;
        Scriptable parent = ScriptableObject.getTopLevelScope(this);
        return Context.javaToJS(writer, parent);
    }
521276
function write(writer, ttf) {

    var hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false;
    ttf.glyf.forEach(function (glyf, index) {

        // 非复合图元没有轮廓则不写
        if (!glyf.compound && (!glyf.contours || 0 === glyf.contours.length)) {
            return;
        }

        // header
        writer.writeInt16(glyf.compound ? -1 : glyf.contours.length);
        writer.writeInt16(glyf.xMin);
        writer.writeInt16(glyf.yMin);
        writer.writeInt16(glyf.xMax);
        writer.writeInt16(glyf.yMax);

        var i;
        var l;
        var flags;

        // 复合图元
        if (glyf.compound) {

            for (i = 0, l = glyf.glyfs.length; i < l; i++) {

                flags = componentFlag.ARGS_ARE_XY_VALUES
                    + componentFlag.ROUND_XY_TO_GRID; // xy values

                // more components
                if (i < l - 1) {
                    flags += componentFlag.MORE_COMPONENTS;
                }

                var g = glyf.glyfs[i];

                // use my metrics
                flags += g.useMyMetrics ? componentFlag.USE_MY_METRICS : 0;
                // overlap compound
                flags += g.overlapCompound ? componentFlag.OVERLAP_COMPOUND : 0;

                var transform = g.transform;
                var a = transform.a;
                var b = transform.b;
                var c = transform.c;
                var d = transform.d;
                var e = transform.e;
                var f = transform.f;

                // xy values or points
                // int 8 放不下，则用int16放
                if (e < 0 || e > 0x7F || f < 0 || f > 0x7F) {
                    flags += componentFlag.ARG_1_AND_2_ARE_WORDS;
                }

                if (b || c) {
                    flags += componentFlag.WE_HAVE_A_TWO_BY_TWO;
                }
                else {
                    if ((a !== 1 || d !== 1) && a === d) {
                        flags += componentFlag.WE_HAVE_A_SCALE;
                    }
                    else if (a !== 1 || d !== 1) {
                        flags += componentFlag.WE_HAVE_AN_X_AND_Y_SCALE;
                    }
                }

                writer.writeUint16(flags);
                writer.writeUint16(g.glyphIndex);

                if (componentFlag.ARG_1_AND_2_ARE_WORDS & flags) {
                    writer.writeInt16(e);
                    writer.writeInt16(f);

                }
                else {
                    writer.writeUint8(e);
                    writer.writeUint8(f);
                }

                if (componentFlag.WE_HAVE_A_SCALE & flags) {
                    writer.writeInt16(Math.round(a * 16384));
                }
                else if (componentFlag.WE_HAVE_AN_X_AND_Y_SCALE & flags) {
                    writer.writeInt16(Math.round(a * 16384));
                    writer.writeInt16(Math.round(d * 16384));
                }
                else if (componentFlag.WE_HAVE_A_TWO_BY_TWO & flags) {
                    writer.writeInt16(Math.round(a * 16384));
                    writer.writeInt16(Math.round(b * 16384));
                    writer.writeInt16(Math.round(c * 16384));
                    writer.writeInt16(Math.round(d * 16384));
                }
            }

        }
        else {

            var endPtsOfContours = -1;
            glyf.contours.forEach(function (contour) {
                endPtsOfContours += contour.length;
                writer.writeUint16(endPtsOfContours);
            });

            // instruction
            if (hinting && glyf.instructions) {
                var instructions = glyf.instructions;
                writer.writeUint16(instructions.length);
                for (i = 0, l = instructions.length; i < l; i++) {
                    writer.writeUint8(instructions[i]);
                }
            }
            else {
                writer.writeUint16(0);
            }


            // 获取暂存中的flags
            flags = ttf.support.glyf[index].flags;
            for (i = 0, l = flags.length; i < l; i++) {
                writer.writeUint8(flags[i]);
            }

            var xCoord = ttf.support.glyf[index].xCoord;
            for (i = 0, l = xCoord.length; i < l; i++) {
                if (0 <= xCoord[i] && xCoord[i] <= 0xFF) {
                    writer.writeUint8(xCoord[i]);
                }
                else {
                    writer.writeInt16(xCoord[i]);
                }
            }

            var yCoord = ttf.support.glyf[index].yCoord;
            for (i = 0, l = yCoord.length; i < l; i++) {
                if (0 <= yCoord[i] && yCoord[i] <= 0xFF) {
                    writer.writeUint8(yCoord[i]);
                }
                else {
                    writer.writeInt16(yCoord[i]);
                }
            }
        }

        // 4字节对齐
        var glyfSize = ttf.support.glyf[index].glyfSize;

        if (glyfSize % 4) {
            writer.writeEmpty(4 - glyfSize % 4);
        }
    });

    return writer;
}
302667
function(arg) {

            var segments = this.segments;
            var numSegments = segments.length;
            // works even if path has no segments

            var currentSegment;

            var previousSegment = ((numSegments !== 0) ? segments[numSegments - 1] : null); // if we are appending to an empty path, previousSegment is null
            var nextSegment = null;

            if (!Array.isArray(arg)) { // arg is a segment
                if (!arg || !arg.isSegment) throw new Error('Segment required.');

                currentSegment = this.prepareSegment(arg, previousSegment, nextSegment);
                segments.push(currentSegment);

            } else { // arg is an array of segments
                if (!arg[0].isSegment) throw new Error('Segments required.');

                var n = arg.length;
                for (var i = 0; i < n; i++) {

                    var currentArg = arg[i];
                    currentSegment = this.prepareSegment(currentArg, previousSegment, nextSegment);
                    segments.push(currentSegment);
                    previousSegment = currentSegment;
                }
            }
        }
872933
function segments2Contours(segments) {

    // 解析segments
    var contours = [];
    var contour = [];
    var prevX = 0;
    var prevY = 0;
    var segment;
    var args;
    var cmd;
    var relative;
    var q;
    var ql;
    var px;
    var py;
    var cubicList;
    var p1;
    var p2;
    var c1;
    var c2;
    var prevCubicC1; // 三次贝塞尔曲线前一个控制点，用于绘制`s`命令

    for (var i = 0, l = segments.length; i < l; i++) {
        segment = segments[i];
        cmd = segment.cmd;
        relative = segment.relative;
        args = segment.args;

        if (cmd === 'Z') {
            contours.push(contour);
            contour = [];
        }
        else if (cmd === 'M' || cmd === 'L') {

            if (args.length < 2 || args.length % 2) {
                throw 'path `M` command needs even params';
            }

            // 这里可能会连续绘制，最后一个是终点
            if (relative) {
                px = prevX;
                py = prevY;
            }
            else {
                px = 0;
                py = 0;
            }

            for (q = 0, ql = args.length; q < ql; q += 2) {

                if (relative) {
                    px += args[q];
                    py += args[q + 1];
                }
                else {
                    px = args[q];
                    py = args[q + 1];
                }

                contour.push({
                    x: px,
                    y: py,
                    onCurve: true
                });
            }

            prevX = px;
            prevY = py;
        }
        else if (cmd === 'H') {

            if (relative) {
                prevX += args[0];
            }
            else {
                prevX = args[0];
            }

            contour.push({
                x: prevX,
                y: prevY,
                onCurve: true
            });
        }
        else if (cmd === 'V') {

            if (relative) {
                prevY += args[0];
            }
            else {
                prevY = args[0];
            }

            contour.push({
                x: prevX,
                y: prevY,
                onCurve: true
            });
        }
        // 二次贝塞尔
        else if (cmd === 'Q') {

            // 这里可能会连续绘制，最后一个是终点
            if (relative) {
                px = prevX;
                py = prevY;
            }
            else {
                px = 0;
                py = 0;
            }

            for (q = 0, ql = args.length; q < ql; q += 4) {

                contour.push({
                    x: px + args[q],
                    y: py + args[q + 1]
                });
                contour.push({
                    x: px + args[q + 2],
                    y: py + args[q + 3],
                    onCurve: true
                });

                if (relative) {
                    px += args[q + 2];
                    py += args[q + 3];
                }
                else {
                    px = 0;
                    py = 0;
                }
            }

            if (relative) {
                prevX = px;
                prevY = py;
            }
            else {
                prevX = args[ql - 2];
                prevY = args[ql - 1];
            }
        }
        // 二次贝塞尔平滑
        else if (cmd === 'T') {

            // 这里需要移除上一个曲线的终点
            var last = contour.pop();

            var pc = contour[contour.length - 1];

            contour.push(pc = {
                x: 2 * last.x - pc.x,
                y: 2 * last.y - pc.y
            });

            px = prevX;
            py = prevY;

            for (q = 0, ql = args.length - 2; q < ql; q += 2) {

                if (relative) {
                    px += args[q];
                    py += args[q + 1];
                }
                else {
                    px = args[q];
                    py = args[q + 1];
                }

                last = {
                    x: px,
                    y: py
                };

                contour.push(pc = {
                    x: 2 * last.x - pc.x,
                    y: 2 * last.y - pc.y
                });
            }

            if (relative) {
                prevX = px + args[ql];
                prevY = py + args[ql + 1];
            }
            else {
                prevX = args[ql];
                prevY = args[ql + 1];
            }

            contour.push({
                x: prevX,
                y: prevY,
                onCurve: true
            });

        }
        // 三次贝塞尔
        else if (cmd === 'C') {

            // 这里可能会连续绘制，最后一个是终点
            cubicList = [];

            if (relative) {
                px = prevX;
                py = prevY;
            }
            else {
                px = 0;
                py = 0;
            }

            p1 = {
                x: prevX,
                y: prevY
            };

            for (q = 0, ql = args.length; q < ql; q += 6) {

                c1 = {
                    x: px + args[q],
                    y: py + args[q + 1]
                };

                c2 = {
                    x: px + args[q + 2],
                    y: py + args[q + 3]
                };

                p2 = {
                    x: px + args[q + 4],
                    y: py + args[q + 5]
                };

                cubicList.push([p1, c1, c2, p2]);

                p1 = p2;

                if (relative) {
                    px += args[q + 4];
                    py += args[q + 5];
                }
                else {
                    px = 0;
                    py = 0;
                }
            }

            if (relative) {
                prevX = px;
                prevY = py;
            }
            else {
                prevX = args[ql - 2];
                prevY = args[ql - 1];
            }

            cubic2Points(cubicList, contour);
            prevCubicC1 = cubicList[cubicList.length - 1][2];
        }
        // 三次贝塞尔平滑
        else if (cmd === 'S') {

            // 这里可能会连续绘制，最后一个是终点
            cubicList = [];

            if (relative) {
                px = prevX;
                py = prevY;
            }
            else {
                px = 0;
                py = 0;
            }

            // 这里需要移除上一个曲线的终点
            p1 = contour.pop();
            c1 = {
                x: 2 * p1.x - prevCubicC1.x,
                y: 2 * p1.y - prevCubicC1.y
            };

            for (q = 0, ql = args.length; q < ql; q += 4) {

                c2 = {
                    x: px + args[q],
                    y: py + args[q + 1]
                };

                p2 = {
                    x: px + args[q + 2],
                    y: py + args[q + 3]
                };

                cubicList.push([p1, c1, c2, p2]);

                p1 = p2;

                c1 = {
                    x: 2 * p1.x - c2.x,
                    y: 2 * p1.y - c2.y
                };

                if (relative) {
                    px += args[q + 2];
                    py += args[q + 3];
                }
                else {
                    px = 0;
                    py = 0;
                }
            }

            if (relative) {
                prevX = px;
                prevY = py;
            }
            else {
                prevX = args[ql - 2];
                prevY = args[ql - 1];
            }

            cubic2Points(cubicList, contour);
            prevCubicC1 = cubicList[cubicList.length - 1][2];
        }
        // 求弧度, rx, ry, angle, largeArc, sweep, ex, ey
        else if (cmd === 'A') {

            if (args.length !== 7) {
                throw 'arc command params error:' + args.join(',');
            }

            var ex = args[5];
            var ey = args[6];

            if (relative) {
                ex = prevX + ex;
                ey = prevY + ey;
            }

            var path = getArc(
                args[0], args[1],
                args[2], args[3], args[4],
                {x: prevX, y: prevY},
                {x: ex, y: ey}
            );

            if (path && path.length > 1) {
                for (q = 1, ql = path.length; q < ql; q++) {
                    contour.push(path[q]);
                }
            }

            prevX = ex;
            prevY = ey;
        }
    }

    return contours;
}
1148123
function process(segments, parent) {
  var last = segments.pop();
  if (last) {
    parent[last] = parent[last] || {};
    process(segments, parent[last]);
  } else {
    parent[true] = true;
  }
}
529663
private Writer doWrite(Writer writer, int indentFactor, int indent) throws IOException {
		writer.write(CharUtil.BRACKET_START);
		final int newindent = indent + indentFactor;
		final boolean isIgnoreNullValue = this.config.isIgnoreNullValue();
		boolean isFirst = true;
		for (Object obj : this.rawList) {
			if(ObjectUtil.isNull(obj) && isIgnoreNullValue) {
				continue;
			}
			if (isFirst) {
				isFirst = false;
			}else {
				writer.write(CharUtil.COMMA);
			}
			
			if (indentFactor > 0) {
				writer.write(CharUtil.LF);
			}
			InternalJSONUtil.indent(writer, newindent);
			InternalJSONUtil.writeValue(writer, obj, indentFactor, newindent, this.config);
		}
		
		if (indentFactor > 0) {
			writer.write(CharUtil.LF);
		}
		InternalJSONUtil.indent(writer, indent);
		writer.write(CharUtil.BRACKET_END);
		return writer;
	}
390415
public void xmlWriteOn(FormattedWriter writer) throws IOException 
    {
        writer.newLine();
        writer.startTag(XML_ITEM_MAP);
        writer.indent();
        for (int i = 0; i < _subMaps.length; i++)
        {
            Iterator iterator = _subMaps[i].values().iterator();
            while (iterator.hasNext())
            {
                writer.newLine();
                AbstractItemLink ail = (AbstractItemLink) iterator.next();
                ail.xmlShortWriteOn(writer);
            }
        }
        writer.outdent();
        writer.newLine();
        writer.endTag(XML_ITEM_MAP);
    }
807432
@Override
  public List<? extends OutputWriter<ByteBuffer>> createWriters(int numShards) {
    ImmutableList.Builder<SizeSegmentingGoogleCloudStorageFileWriter> result =
        new ImmutableList.Builder<>();
    for (int i = 0; i < numShards; ++i) {
      result.add(new SizeSegmentingGoogleCloudStorageFileWriter(bucket, fileNamePattern, i,
          mimeType, segmentSizeLimit));
    }
    return result.build();
  }
691636
@GwtIncompatible("Writer")
  static CharOutput asCharOutput(final Writer writer) {
    checkNotNull(writer);
    return new CharOutput() {
      @Override
      public void write(char c) throws IOException {
        writer.append(c);
      }

      @Override
      public void flush() throws IOException {
        writer.flush();
      }

      @Override
      public void close() throws IOException {
        writer.close();
      }
    };
  }
151751
public void writeTokens(Writer writer, boolean useLemmas, boolean useNormNer) throws IOException {
        for (int i=0; i<tokens.size(); i++) {
            AgigaToken tok = tokens.get(i);
            if (useNormNer && tok.getNormNer() != null) {
                require(prefs.readNormNer, 
                        "AgigaPrefs.readNormNer must be true if useNormNer=true for writeTokens()");
                writer.write(tok.getNormNer());
            } else if (useLemmas) {
                require(prefs.readLemma, 
                        "AgigaPrefs.readLemma must be true if useLemmas=true for writeTokens()");
                writer.write(tok.getLemma());
            } else {
                require(prefs.readWord, 
                        "AgigaPrefs.readWord must be true if useLemmas and useNormNer are false for writeTokens()");
                writer.write(tok.getWord());                
            }
            if (i < tokens.size()-1) {
                writer.write(" ");
            }
        }
        writer.write("\n");
    }
1158580
function buildHTML(segments) {
		var html = '';
		for (var i=0; i<segments.length; i++) {
			html += buildHTMLForSegment(segments[i]);
		}
		return html;
	}
734416
def _write_segments(self, filename):
        
        # Column headers
        shead = '\t'.join(['id', 'multiplicon', 'genome', 'list', 'first',
                           'last', 'order'])
        with open(filename, 'w') as fhandle:
            fhandle.write(shead + '\n')
            for mrow in self.segments:
                fhandle.write('\t'.join([str(e) for e in mrow]) + '\n')