Beispiel #1
0
        /// <Summary>
        /// Encodes the StylusTip in the ISF stream.
        /// </Summary>
#else
        /// <Summary>
        /// Encodes the StylusTip in the ISF stream.
        /// </Summary>
#endif
        private static void PersistStylusTip(DrawingAttributes da, Stream stream, GuidList guidList, ref uint cbData, ref BinaryWriter bw)
        {
            //
            // persist the StylusTip
            //
            if (da.ContainsPropertyData(KnownIds.StylusTip))
            {
                System.Diagnostics.Debug.Assert(da.StylusTip != StylusTip.Ellipse, "StylusTip was put in the EPC for the default value!");

                //
                // persist PenTip.Rectangle for V1 ISF
                //
                Debug.Assert(bw != null);
                cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(KnownIds.PenTip, true));
                cbData += SerializationHelper.Encode(stream, (uint)PenTip.Rectangle);

                using (MemoryStream localStream = new MemoryStream(6)) //reasonable default
                {
                    Int32 stylusTip = Convert.ToInt32(da.StylusTip, System.Globalization.CultureInfo.InvariantCulture);
                    System.Runtime.InteropServices.VarEnum type = SerializationHelper.ConvertToVarEnum(PersistenceTypes.StylusTip, true);
                    ExtendedPropertySerializer.EncodeAttribute(KnownIds.StylusTip, stylusTip, type, localStream);

                    cbData += ExtendedPropertySerializer.EncodeAsISF(KnownIds.StylusTip, localStream.ToArray(), stream, guidList, 0, true);
                }
            }
        }
Beispiel #2
0
        private static void PersistColorAndTransparency(DrawingAttributes da, Stream stream, GuidList guidList, ref uint cbData, ref BinaryWriter bw)
        {
            // if the color is non-default (e.g. not black), then store it
            // the v1 encoder throws away the default color (Black) so it isn't valuable
            // to save.
            if (da.ContainsPropertyData(KnownIds.Color))
            {
                Color daColor = da.Color;
                System.Diagnostics.Debug.Assert(da.Color != (Color)DrawingAttributes.GetDefaultDrawingAttributeValue(KnownIds.Color), "Color was put in the EPC for the default value!");

                //Note: we don't store the alpha value of the color (we don't use it)
                uint r = (uint)daColor.R, g = (uint)daColor.G, b = (uint)(daColor.B);
                uint colorVal = r + (g << Native.BitsPerByte) + (b << (Native.BitsPerByte * 2));

                Debug.Assert(bw != null);
                cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(KnownIds.Color, true));
                cbData += SerializationHelper.Encode(stream, colorVal);
            }

            //set transparency if Color.A is set
            byte alphaChannel = da.Color.A;

            if (alphaChannel != 255)
            {
                //note: Color.A is set to 255 by default, which means fully opaque
                //transparency is just the opposite - 0 means fully opaque so
                //we need to flip the values
                int transparency = MathHelper.AbsNoThrow(((int)alphaChannel) - 255);
                Debug.Assert(bw != null);
                cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(KnownIds.Transparency, true));
                cbData += SerializationHelper.Encode(stream, Convert.ToUInt32(transparency));
            }
        }
Beispiel #3
0
        private static void PersistDrawingFlags(DrawingAttributes da, Stream stream, GuidList guidList, ref uint cbData, ref BinaryWriter bw)
        {
            //
            // always serialize DrawingFlags, even when it is the default of AntiAliased.  V1 loaders
            // expect it.
            //
            Debug.Assert(bw != null);
            cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(KnownIds.DrawingFlags, true));
            cbData += SerializationHelper.Encode(stream, (uint)(int)da.DrawingFlags);

            if (da.ContainsPropertyData(KnownIds.CurveFittingError))
            {
                Debug.Assert(bw != null);
                cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(KnownIds.CurveFittingError, true));
                cbData += SerializationHelper.Encode(stream, (uint)(int)da.GetPropertyData(KnownIds.CurveFittingError));
            }
        }
 /// <summary>
 /// Initializes a MetricEntry based on StylusPointPropertyInfo and default StylusPointPropertyInfo for the property
 /// </summary>
 /// <param name="originalInfo"></param>
 /// <param name="defaultInfo"></param>
 /// <returns></returns>
 public void Initialize(StylusPointPropertyInfo originalInfo, StylusPointPropertyInfo defaultInfo)
 {
     _size = 0;
     using (MemoryStream strm = new MemoryStream(_data))
     {
         if (!DoubleUtil.AreClose(originalInfo.Resolution, defaultInfo.Resolution))
         {
             // First min value
             _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum);
             // Max value
             _size += SerializationHelper.SignEncode(strm, originalInfo.Maximum);
             // Units
             _size += SerializationHelper.Encode(strm, (uint)originalInfo.Unit);
             // resolution
             using (BinaryWriter bw = new BinaryWriter(strm))
             {
                 bw.Write(originalInfo.Resolution);
                 _size += 4; // sizeof(float)
             }
         }
         else if (originalInfo.Unit != defaultInfo.Unit)
         {
             // First min value
             _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum);
             // Max value
             _size += SerializationHelper.SignEncode(strm, originalInfo.Maximum);
             // Units
             _size += SerializationHelper.Encode(strm, (uint)originalInfo.Unit);
         }
         else if (originalInfo.Maximum != defaultInfo.Maximum)
         {
             // First min value
             _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum);
             // Max value
             _size += SerializationHelper.SignEncode(strm, originalInfo.Maximum);
         }
         else if (originalInfo.Minimum != defaultInfo.Minimum)
         {
             _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum);
         }
     }
 }
        /// <summary>
        /// This function Packs the data in the buffer provided. The
        /// function is being called during the save loop and caller
        /// must call GetSize for the block before calling this function.
        /// The buffer must be preallocated and buffer size must be at
        /// least the size of the block.
        /// On return cbBuffer contains the size of the data written.
        /// Called only by BuildMetricTable funtion
        /// </summary>
        /// <param name="strm"></param>
        /// <returns></returns>
        public uint Pack(Stream strm)
        {
            // Write the size of the Block at the begining of the buffer.
            // But first check the validity of the buffer & its size
            uint cbWrite = 0;

            // First write the size of the block
            cbWrite = SerializationHelper.Encode(strm, _size);

            // Now write each entry for the block
            MetricEntry entry = _Entry;

            while (null != entry)
            {
                cbWrite += SerializationHelper.Encode(strm, (uint)entry.Tag);
                cbWrite += SerializationHelper.Encode(strm, entry.Size);
                strm.Write(entry.Data, 0, (int)entry.Size);
                cbWrite += entry.Size;
                entry    = entry.Next;
            }
            return(cbWrite);
        }
Beispiel #6
0
        private static void PersistRasterOperation(DrawingAttributes da, Stream stream, GuidList guidList, ref uint cbData, ref BinaryWriter bw)
        {
            // write any non-default RasterOp value that we might have picked up from
            // V1 interop or by setting IsHighlighter.
            if (da.RasterOperation != DrawingAttributeSerializer.RasterOperationDefaultV1)
            {
                uint ropSize = GuidList.GetDataSizeIfKnownGuid(KnownIds.RasterOperation);
                if (ropSize == 0)
                {
                    throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("ROP data size was not found"));
                }

                Debug.Assert(bw != null);
                cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(KnownIds.RasterOperation, true));
                long currentPosition = stream.Position;
                bw.Write(da.RasterOperation);
                if ((uint)(stream.Position - currentPosition) != ropSize)
                {
                    throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("ROP data was incorrectly serialized"));
                }
                cbData += ropSize;
            }
        }
Beispiel #7
0
        /// <summary>
        /// Serializes the GuidList in the memory stream and returns the size
        /// </summary>
        /// <param name="stream">If null, calculates the size only</param>
        /// <returns></returns>
        public uint Save(Stream stream)
        {
            // calculate the number of custom guids to persist
            //   custom guids are those which are not reserved in ISF via 'tags'
            uint ul = (uint)(_CustomGuids.Count * Native.SizeOfGuid);

            // if there are no custom guids, then the guid list can be persisted
            //      without any cost ('tags' are freely storeable)
            if (ul == 0)
            {
                return(0);
            }

            // if only the size was requested, return it
            if (null == stream)
            {
                return((uint)(ul + SerializationHelper.VarSize(ul) + SerializationHelper.VarSize((uint)KnownTagCache.KnownTagIndex.GuidTable)));
            }

            // encode the guid table tag in the output stream
            uint cbWrote = SerializationHelper.Encode(stream, (uint)KnownTagCache.KnownTagIndex.GuidTable);

            // encode the size of the guid table
            cbWrote += SerializationHelper.Encode(stream, ul);

            // encode each guid in the table
            for (int i = 0; i < _CustomGuids.Count; i++)
            {
                Guid guid = (Guid)_CustomGuids[i];

                stream.Write(guid.ToByteArray(), 0, (int)Native.SizeOfGuid);
            }

            cbWrote += ul;
            return(cbWrote);
        }
Beispiel #8
0
        /// <summary>
        /// Saves the packets into a stream of bytes
        /// </summary>
        /// <param name="stroke">Stroke to save</param>
        /// <param name="stream">null to calculate size only</param>
        /// <param name="compressor"></param>
        /// <param name="strokeLookupEntry"></param>
        /// <returns></returns>
#else
        /// <summary>
        /// Saves the packets into a stream of bytes
        /// </summary>
        /// <param name="stroke">Stroke to save</param>
        /// <param name="stream">null to calculate size only</param>
        /// <param name="strokeLookupEntry"></param>
#endif
        static uint SavePackets(
            Stroke stroke,
            Stream stream,
#if OLD_ISF
            Compressor compressor,
#endif
            StrokeCollectionSerializer.StrokeLookupEntry strokeLookupEntry)
        {
            // First write or calculate how many points are there
            uint pointCount        = (uint)stroke.StylusPoints.Count;
            uint localBytesWritten = (stream != null) ? SerializationHelper.Encode(stream, pointCount) : SerializationHelper.VarSize(pointCount);
            byte compressionAlgorithm;

            int[][] outputArrays = strokeLookupEntry.ISFReadyStrokeData;
            //We don't serialize button data
            //int valuesPerPoint = stroke.StylusPoints.Description.GetOutputArrayLengthPerPoint();
            //int buttonCount = stroke.StylusPoints.Description.ButtonCount;

            ReadOnlyCollection <StylusPointPropertyInfo> propertyInfos
                = stroke.StylusPoints.Description.GetStylusPointProperties();

            int i = 0;

            for (; i < propertyInfos.Count; i++)
            {
                StylusPointPropertyInfo propertyInfo = propertyInfos[i];
                if (i == 2 && !strokeLookupEntry.StorePressure)
                {
                    //
                    // only store pressure if we need to
                    //
                    continue;
                }
                if (propertyInfo.IsButton)
                {
                    //
                    // we're at the buttons, handle this below
                    //
                    break;
                }
                compressionAlgorithm = strokeLookupEntry.CompressionData;
                localBytesWritten   += SavePacketPropertyData(outputArrays[i],
                                                              stream,
#if OLD_ISF
                                                              compressor,
#endif
                                                              propertyInfo.Id,
                                                              ref compressionAlgorithm);
            }

            /*
             * We don't serialize button data
             * // Now write all button data. Button data is stored as if it is another packet property
             * // with size (cbuttoncount + 7)/8 bytes and corresponding guids are stored in the packet
             * // description. Button data is only stored if buttons are present in the description and there
             * // are packets in the stroke
             * if (buttonCount > 0 && pointCount > 0)
             * {
             *  Debug.Assert(i == valuesPerPoint - 1);
             *  BitStreamWriter bitWriter = new BitStreamWriter();
             *  //
             *  // Get the array of button data (i is still pointing at it)
             *  //
             *  int[] buttonData = outputArrays[i];
             *
             *  for (int x = 0; x < pointCount; x++)
             *  {
             *      //
             *      // each int in the button data array contains buttonCount number
             *      // of bits that need to be written to the BitStreamWriter
             *      // the BitStreamWriter takes bytes at a time.  We always write the most
             *      // signifigant bits first
             *      //
             *      int uncompactedButtonDataForPoint = buttonData[x];
             *
             *      // calculate the number of full bytes used for buttons per packet
             *      //   Example: 10 buttons would require 1 full byte
             *      //            but 8 would require
             *      int fullBytesForButtonsPerPacket = buttonCount / Native.BitsPerByte;
             *
             *      // calculate the number of bits that spill beyond the full byte boundary
             *      //   Example: 10 buttons would require 2 extra bits (8 fit in a full byte)
             *      int bitsToWrite = buttonCount % Native.BitsPerByte;
             *
             *      for (; fullBytesForButtonsPerPacket >= 0; fullBytesForButtonsPerPacket--)
             *      {
             *          byte byteOfButtonData =
             *              Convert.ToByte(uncompactedButtonDataForPoint >> (fullBytesForButtonsPerPacket * Native.BitsPerByte));
             *          //
             *          // write 8 or less bytes to the bitwriter
             *          // checking for 0 handles the case where we're writing 8, 16 or 24 bytes
             *          // and bitsToWrite is initialize to zero
             *          //
             *          if (bitsToWrite > 0)
             *          {
             *              bitWriter.Write(byteOfButtonData, bitsToWrite);
             *          }
             *          if (fullBytesForButtonsPerPacket > 0)
             *          {
             *              bitsToWrite = Native.BitsPerByte;
             *          }
             *      }
             *  }
             *
             *  // retrieve the button bytes
             *  byte[] packedButtonData = bitWriter.ToBytes();
             *
             *  if (packedButtonData.Length !=
             *      ((buttonCount * pointCount + 7) / Native.BitsPerByte))
             *  {
             *      throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Packed button length not equal to expected length"));
             *  }
             *
             *  // write out the packed button data to the output stream
             *  stream.Write(packedButtonData, 0, packedButtonData.Length);
             *  localBytesWritten += (uint)packedButtonData.Length;
             * }
             */

            return(localBytesWritten);
        }
Beispiel #9
0
        private static void PersistWidthHeight(DrawingAttributes da, Stream stream, GuidList guidList, ref uint cbData, ref BinaryWriter bw)
        {
            //persist the height and width
            // For v1 loaders we persist height and width in StylusHeight and StylusWidth
            double stylusWidth  = da.Width;
            double stylusHeight = da.Height;

            // Save the pen tip's width and height.
            for (int i = 0; i < 2; i++)
            {
                Guid   guid = (i == 0) ? KnownIds.StylusWidth : KnownIds.StylusHeight;
                double size = (0 == i) ? stylusWidth : stylusHeight;

                //
                // the size is now in Avalon units, we need to convert to HIMETRIC
                //
                size *= StrokeCollectionSerializer.AvalonToHimetricMultiplier;

                double sizeWhenMissing = (0 == i) ? V1PenWidthWhenWidthIsMissing : V1PenHeightWhenHeightIsMissing;

                //
                // only persist height / width if they are equal to the height / width
                // when missing in the isf stream OR for compatibility with V1
                //
                bool skipPersisting = DoubleUtil.AreClose(size, sizeWhenMissing);
                if (stylusWidth == stylusHeight &&
                    da.StylusTip == StylusTip.Ellipse &&
                    guid == KnownIds.StylusHeight &&
                    da.HeightChangedForCompatabity)
                {
                    //we need to put height in the ISF stream for compat
                    skipPersisting = true;
                }


                if (!skipPersisting)
                {
                    uint uIntegral = (uint)(size + 0.5f);

                    Debug.Assert(bw != null);
                    cbData += SerializationHelper.Encode(stream, (uint)guidList.FindTag(guid, true));
                    cbData += SerializationHelper.Encode(stream, uIntegral);

                    short sFraction = (size > uIntegral) ? (short)(DrawingAttributes.StylusPrecision * (size - uIntegral) + 0.5f) : (short)(DrawingAttributes.StylusPrecision * (size - uIntegral) - 0.5);

                    // If the fractional values is non zero, we store this value along with TAG_MANTISSA and size with a precisson of 1000
                    if (0 != sFraction)
                    {
                        uint cb = Native.SizeOfUShort; // For header NO_COMPRESS

                        Debug.Assert(bw != null);
                        cbData += SerializationHelper.Encode(stream, (uint)MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.Mantissa);
                        cbData += SerializationHelper.Encode(stream, cb);
                        bw.Write((byte)0x00);
                        bw.Write((short)sFraction);

                        cbData += cb + 1; // include size of encoded 0 and encoded fraction value
                    }
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Encodes a custom attribute to the ISF stream
        /// </summary>
#endif
        internal static uint EncodeAsISF(Guid id, byte[] data, Stream strm, GuidList guidList, byte compressionAlgorithm, bool fTag)
        {
            uint cbWrite = 0;
            uint cbSize  = GuidList.GetDataSizeIfKnownGuid(id);

            Debug.Assert(strm != null);

            if (fTag)
            {
                uint uTag = (uint)guidList.FindTag(id, true);

                cbWrite += SerializationHelper.Encode(strm, uTag);
            }

            // If cbSize is 0, it is either a custom property or a known property with 0
            // size. In either case, we need to write the size of the individual object
            if (0 == cbSize)
            {
                // Now we need to write the actual data for the property
                cbSize = (uint)data.Length;

                byte[] compresseddata = Compressor.CompressPropertyData(data, compressionAlgorithm);

#if OLD_ISF
                byte nAlgo = compressionAlgorithm;
                uint cbOut = 0;

                Compressor.CompressPropertyData(data, ref nAlgo, ref cbOut, null);

                // Allocate a buffer big enough to hold the compressed data
                byte[] compresseddata2 = new byte[cbOut];

                // NativeCompressor the data
                Compressor.CompressPropertyData(data, ref nAlgo, ref cbOut, compresseddata2);

                if (compresseddata.Length != compresseddata2.Length)
                {
                    throw new InvalidOperationException("MAGIC EXCEPTION: Property bytes length when compressed didn't match with new compression");
                }
                for (int i = 0; i < compresseddata.Length; i++)
                {
                    if (compresseddata[i] != compresseddata2[i])
                    {
                        throw new InvalidOperationException("MAGIC EXCEPTION: Property data didn't match with new property compression at index " + i.ToString());
                    }
                }
#endif

                // write the encoded compressed size minus the algo byte
                cbWrite += SerializationHelper.Encode(strm, (uint)(compresseddata.Length - 1));

                // Write the raw data
                strm.Write(compresseddata, 0, (int)compresseddata.Length);
                cbWrite += (uint)compresseddata.Length;
            }
            else
            {
                //
                // note that we used to write the nocompression byte, but that
                // was incorrect.  We must not write it because loaders do not
                // expect it for known guids
                //
                // write the algo byte
                //strm.WriteByte(Compressor.NoCompression);
                //cbWrite++;

                // write the raw data without compression
                strm.Write(data, 0, (int)data.Length);
                cbWrite += (uint)data.Length;
            }

            return(cbWrite);
        }