/// <summary> /// ReadDisplayText reads a structure designed to hold display text. /// </summary> /// <remarks> /// This methods aplies when the specifications are mentionning the availability of a OIAN_TEXTPRIVDATA structure. /// </remarks> /// <param name="stream">The stream to read the data in.</param> /// <param name="dataSize">The size of the data to read.</param> /// <returns>The data read.</returns> public static WangDisplayText ReadDisplayText(IWangStream stream, int dataSize) { // At least 4 values with 4 bytes are required if (dataSize >= 16) { /* * Type Name Description * int nCurrentOrientation Angle of text baseline to image in tenths of a degree; valid values are 0, 900, 1800, 2700. * * UINT uReserved1 Always 1000 when writing ignore when reading. * * UINT uCreationScale Always 72000 divided by the vertical resolution of the base image when writing. * Used to modify the Attributes.lfFont.lfHeight variable for display. * * UINT uAnoTextLength 64K byte limit (32K for multi-byte data) for Attach-a-Note, typed text, text from file; * 255 byte limit for text stamp. * * char szAnoText[*] Text string for text mark types. */ int orientation = stream.ReadInt32(); #if DEBUG Debug.Assert(orientation == 0 || orientation == 900 || orientation == 1800 || orientation == 2700); #endif // DEBUG UInt32 uReserved1 = stream.ReadUint32(); #if DEBUG // 1000 is the value described within the specs but we have some cases with something else. // Debug.Assert(uReserved1 == 1000 ); #endif // DEBUG uint creationScale = stream.ReadUint32(); int textSize = (int)stream.ReadUint32(); // It is necessary to have enough data for the characters. if (textSize <= (dataSize - 16)) { string text = WangAnnotationStructureReader.ReadCharString(stream, textSize); stream.SkipBytes(dataSize - 16 - textSize); return(new WangDisplayText(orientation, creationScale, text)); } } return(null); }
/// <summary> /// ReadNamedBlockHeader reads a named block header. /// </summary> /// <param name="stream">The stream to read the data in.</param> /// <param name="count">The number of bytes to character to read in the buffer.</param> /// <returns>The data read, null if an error occurred.</returns> public static WangNamedBlockHeader ReadNamedBlockHeader(IWangStream stream, int count) { // The expected data size is fixed. if (count == 12) { /* * 8 bytes = name of named block * 4 bytes = size (n) of named block * 4 bytes = reserved. Only present and necessary with Intel 16-bit format. Skip on read and write as zeros. */ WangNamedBlockHeader header = new WangNamedBlockHeader(WangAnnotationStructureReader.ReadCharString(stream, 8), stream.ReadInt32()); // TODO - David Ometto - 2016-11-21 - Add support for non Intel, big endian and 16 bit fun to handle here // Only present and necessary with Intel 16-bit format. Skip on read and write as zeros. return(header); } return(null); }
/// <summary> /// ReadBlock reads the block and updates the properties accordingly. /// </summary> /// <param name="properties">The properties to update.</param> /// <param name="stream">The stream to read the data in.</param> /// <param name="dataSize">The size of the block.</param> /// <returns>true if the operation succeeded otherwise returns false.</returns> public static bool ReadBlock(WangAnnotationProperties properties, IWangStream stream, int dataSize) { #if DEBUG Debug.Assert(stream.AvailableBytes() >= dataSize); #endif // DEBUG WangNamedBlockHeader header = WangAnnotationStructureReader.ReadNamedBlockHeader(stream, dataSize); if (header == null || header.Size > stream.AvailableBytes()) { return(false); } /* * Named Block Associated Structure Usage * OiAnoDat For lines: AN_POINTS List coordinates for lines and freehand marks. * For images:AN_NEW_ROTATE_STRUCT Hold scaling and resolution information for image marks. * OiFilNam AN_NAME_STRUCT Hold file name for image marks. * OiDIB AN_IMAGE_STRUCT Store DIB data. * OiGroup (required) STR Create sets of marks (required). * OiIndex (required) STR Assign unique number, originating at 0, for each mark. * To facilitate easy application control, the next available number is generated by incrementing by 1 the number just assigned and storing it in the default OiIndex mark. * OiAnText OIAN_TEXTPRIVDATA Display text annotation marks. * OiHypLnk HYPERLINK_NB Turn mark into a hyperlink. */ if (header.Name == "OiAnoDat") { // TODO - David Ometto - 2016-11-24 - Unit test this method return(ReadAnoDatBlock(properties, stream, header.Size)); } else if (header.Name == "OiFilNam") { properties.SetFilename(WangAnnotationStructureReader.ReadCharString(stream, header.Size)); return(true); } else if (header.Name == "OiDIB") { properties.SetDibInfo(WangAnnotationStructureReader.ReadDib(stream, header.Size)); return(true); } else if (header.Name == "OiGroup") { properties.OiGroup = WangAnnotationStructureReader.ReadCharString(stream, header.Size); return(true); } else if (header.Name == "OiIndex") { properties.OiIndex = WangAnnotationStructureReader.ReadCharString(stream, header.Size); return(true); } else if (header.Name == "OiAnText") { WangDisplayText displayText = WangAnnotationStructureReader.ReadDisplayText(stream, header.Size); if (displayText == null) { return(false); } properties.SetDisplayText(displayText); return(true); } else if (header.Name == "OiHypLnk") { WangHyperlink hyperlink = WangAnnotationStructureReader.ReadHyperlink(stream, header.Size); if (hyperlink == null) { return(false); } properties.SetHyperlink(hyperlink); return(true); } else { // We just skip unknown data stream.SkipBytes(header.Size); return(true); } }