///<summary> /// Callback method, used for adding a figure to the list ///</summary> ///<param name="isFilled"> /// The figure is filled ///</param> ///<param name="isClosed"> /// The figure is closed ///</param> ///<param name="pPoints"> /// The array of the figure's defining points ///</param> ///<param name="pointCount"> /// The size of the points array ///</param> ///<param name="pSegTypes"> /// The array of the figure's defining segment types ///</param> ///<param name="segmentCount"> /// The size of the types array ///</param> internal unsafe void AddFigureToList(bool isFilled, bool isClosed, MilPoint2F *pPoints, UInt32 pointCount, byte *pSegTypes, UInt32 segmentCount) { if (pointCount >= 1 && segmentCount >= 1) { PathFigure figure = new PathFigure(); figure.IsFilled = isFilled; figure.StartPoint = new Point(pPoints->X, pPoints->Y); int pointIndex = 1; int sameSegCount = 0; for (int segIndex = 0; segIndex < segmentCount; segIndex += sameSegCount) { byte segType = (byte)(pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegTypeMask); sameSegCount = 1; // Look for a run of same-type segments for a PolyXXXSegment. while (((segIndex + sameSegCount) < segmentCount) && (pSegTypes[segIndex] == pSegTypes[segIndex + sameSegCount])) { sameSegCount++; } bool fStroked = (pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegIsAGap) == (byte)0; bool fSmooth = (pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegSmoothJoin) != (byte)0; if (segType == (byte)MILCoreSegFlags.SegTypeLine) { if (pointIndex + sameSegCount > pointCount) { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } if (sameSegCount > 1) { PointCollection ptCollection = new PointCollection(); for (int i = 0; i < sameSegCount; i++) { ptCollection.Add(new Point(pPoints[pointIndex + i].X, pPoints[pointIndex + i].Y)); } ptCollection.Freeze(); PolyLineSegment polySeg = new PolyLineSegment(ptCollection, fStroked, fSmooth); polySeg.Freeze(); figure.Segments.Add(polySeg); } else { Debug.Assert(sameSegCount == 1); figure.Segments.Add(new LineSegment(new Point(pPoints[pointIndex].X, pPoints[pointIndex].Y), fStroked, fSmooth)); } pointIndex += sameSegCount; } else if (segType == (byte)MILCoreSegFlags.SegTypeBezier) { int pointBezierCount = sameSegCount * 3; if (pointIndex + pointBezierCount > pointCount) { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } if (sameSegCount > 1) { PointCollection ptCollection = new PointCollection(); for (int i = 0; i < pointBezierCount; i++) { ptCollection.Add(new Point(pPoints[pointIndex + i].X, pPoints[pointIndex + i].Y)); } ptCollection.Freeze(); PolyBezierSegment polySeg = new PolyBezierSegment(ptCollection, fStroked, fSmooth); polySeg.Freeze(); figure.Segments.Add(polySeg); } else { Debug.Assert(sameSegCount == 1); figure.Segments.Add(new BezierSegment( new Point(pPoints[pointIndex].X, pPoints[pointIndex].Y), new Point(pPoints[pointIndex + 1].X, pPoints[pointIndex + 1].Y), new Point(pPoints[pointIndex + 2].X, pPoints[pointIndex + 2].Y), fStroked, fSmooth)); } pointIndex += pointBezierCount; } else { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } } if (isClosed) { figure.IsClosed = true; } figure.Freeze(); Figures.Add(figure); // Do not bother adding empty figures. } }
/// <summary> /// Captures this device to a particular element. /// </summary> /// <param name="element">The element this device will be captured to.</param> /// <param name="captureMode">The type of capture to use.</param> /// <returns>true if capture was changed, false otherwise.</returns> public bool Capture(IInputElement element, CaptureMode captureMode) { VerifyAccess(); // If the element is null or captureMode is None, ensure // that the other parameter is consistent. if ((element == null) || (captureMode == CaptureMode.None)) { element = null; captureMode = CaptureMode.None; } UIElement uiElement; ContentElement contentElement; UIElement3D uiElement3D; CastInputElement(element, out uiElement, out contentElement, out uiElement3D); if ((element != null) && (uiElement == null) && (contentElement == null) && (uiElement3D == null)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement, element.GetType()), "element"); } if (_captured != element) { // Ensure that the new element is visible and enabled if ((element == null) || (((uiElement != null) && uiElement.IsVisible && uiElement.IsEnabled) || ((contentElement != null) && contentElement.IsEnabled) || ((uiElement3D != null) && uiElement3D.IsVisible && uiElement3D.IsEnabled))) { IInputElement oldCapture = _captured; _captured = element; _captureMode = captureMode; UIElement oldUIElement; ContentElement oldContentElement; UIElement3D oldUIElement3D; CastInputElement(oldCapture, out oldUIElement, out oldContentElement, out oldUIElement3D); if (oldUIElement != null) { oldUIElement.IsEnabledChanged -= OnReevaluateCapture; oldUIElement.IsVisibleChanged -= OnReevaluateCapture; oldUIElement.IsHitTestVisibleChanged -= OnReevaluateCapture; } else if (oldContentElement != null) { oldContentElement.IsEnabledChanged -= OnReevaluateCapture; } else if (oldUIElement3D != null) { oldUIElement3D.IsEnabledChanged -= OnReevaluateCapture; oldUIElement3D.IsVisibleChanged -= OnReevaluateCapture; oldUIElement3D.IsHitTestVisibleChanged -= OnReevaluateCapture; } if (uiElement != null) { uiElement.IsEnabledChanged += OnReevaluateCapture; uiElement.IsVisibleChanged += OnReevaluateCapture; uiElement.IsHitTestVisibleChanged += OnReevaluateCapture; } else if (contentElement != null) { contentElement.IsEnabledChanged += OnReevaluateCapture; } else if (uiElement3D != null) { uiElement3D.IsEnabledChanged += OnReevaluateCapture; uiElement3D.IsVisibleChanged += OnReevaluateCapture; uiElement3D.IsHitTestVisibleChanged += OnReevaluateCapture; } UpdateReverseInheritedProperty(/* capture = */ true, oldCapture, _captured); if (oldCapture != null) { DependencyObject o = oldCapture as DependencyObject; o.SetValue(UIElement.AreAnyTouchesCapturedPropertyKey, BooleanBoxes.Box(AreAnyTouchesCapturedOrDirectlyOver(oldCapture, /* isCapture = */ true))); } if (_captured != null) { DependencyObject o = _captured as DependencyObject; o.SetValue(UIElement.AreAnyTouchesCapturedPropertyKey, BooleanBoxes.TrueBox); } if (oldCapture != null) { RaiseLostCapture(oldCapture); } if (_captured != null) { RaiseGotCapture(_captured); } // Capture successfully moved, notify the subclass. OnCapture(element, captureMode); Synchronize(); return(true); } else { return(false); } } else { return(true); } }
/// <summary> /// Open Media /// </summary> private void OpenMedia(Uri source) { string toOpen = null; if (source != null && source.IsAbsoluteUri && source.Scheme == PackUriHelper.UriSchemePack) { try { source = BaseUriHelper.ConvertPackUriToAbsoluteExternallyVisibleUri(source); } catch (InvalidOperationException) { source = null; _mediaEventsHelper.RaiseMediaFailed(new System.NotSupportedException(SR.Get(SRID.Media_PackURIsAreNotSupported, null))); } } // Setting a null source effectively disconects the MediaElement. if (source != null) { // get the base directory of the application; never expose this Uri appBase = SecurityHelper.GetBaseDirectory(AppDomain.CurrentDomain); // this extracts the URI to open Uri uriToOpen = ResolveUri(source, appBase); toOpen = DemandPermissions(uriToOpen); } else { toOpen = null; } // We pass in exact same URI for which we demanded permissions so that we can be sure // there is no discrepancy between the two. HRESULT.Check(MILMedia.Open(_nativeMedia, toOpen)); }
internal static object Invoke(AutomationPeer peer, DispatcherOperationCallback work, object arg) { Dispatcher dispatcher = peer.Dispatcher; // Null dispatcher likely means the visual is in bad shape! if (dispatcher == null) { throw new ElementNotAvailableException(); } Exception remoteException = null; bool completed = false; object retVal = dispatcher.Invoke( DispatcherPriority.Send, TimeSpan.FromMinutes(3), (DispatcherOperationCallback) delegate(object unused) { try { return(work(arg)); } catch (Exception e) { remoteException = e; return(null); } catch //for non-CLS Compliant exceptions { remoteException = null; return(null); } finally { completed = true; } }, null); if (completed) { if (remoteException != null) { throw remoteException; } } else { bool dispatcherInShutdown = dispatcher.HasShutdownStarted; if (dispatcherInShutdown) { throw new InvalidOperationException(SR.Get(SRID.AutomationDispatcherShutdown)); } else { throw new TimeoutException(SR.Get(SRID.AutomationTimeout)); } } return(retVal); }
private void Init() { if (_ploc.Value == System.IntPtr.Zero) { // Initializing context LsErr lserr = LsErr.None; LsContextInfo contextInfo = new LsContextInfo(); LscbkRedefined lscbkRedef = new LscbkRedefined(); _callbacks = new LineServicesCallbacks(); _callbacks.PopulateContextInfo(ref contextInfo, ref lscbkRedef); contextInfo.version = 4; // we should set this right, they might check it in the future contextInfo.pols = IntPtr.Zero; // This will be filled in the un-managed code contextInfo.cEstimatedCharsPerLine = TextStore.TypicalCharactersPerLine; contextInfo.fDontReleaseRuns = 1; // dont waste time // There are 3 justification priorities right now with one considered good // and the other two provided for emergency expansion. // Future development to enable international justification will likely change this. // e.g. Kashida justification would require more than one good priorities. contextInfo.cJustPriorityLim = 3; // Fill up text configuration contextInfo.wchNull = '\u0000'; contextInfo.wchUndef = '\u0001'; contextInfo.wchTab = '\u0009'; contextInfo.wchPosTab = contextInfo.wchUndef; contextInfo.wchEndPara1 = TextStore.CharParaSeparator; // Unicode para separator contextInfo.wchEndPara2 = contextInfo.wchUndef; contextInfo.wchSpace = '\u0020'; contextInfo.wchHyphen = MS.Internal.Text.TextInterface.TextAnalyzer.CharHyphen; //'\x002d'; contextInfo.wchNonReqHyphen = '\u00AD'; contextInfo.wchNonBreakHyphen = '\u2011'; contextInfo.wchEnDash = '\u2013'; contextInfo.wchEmDash = '\u2014'; contextInfo.wchEnSpace = '\u2002'; contextInfo.wchEmSpace = '\u2003'; contextInfo.wchNarrowSpace = '\u2009'; contextInfo.wchJoiner = '\u200D'; contextInfo.wchNonJoiner = '\u200C'; contextInfo.wchVisiNull = '\u2050'; contextInfo.wchVisiAltEndPara = '\u2051'; contextInfo.wchVisiEndLineInPara = '\u2052'; contextInfo.wchVisiEndPara = '\u2053'; contextInfo.wchVisiSpace = '\u2054'; contextInfo.wchVisiNonBreakSpace = '\u2055'; contextInfo.wchVisiNonBreakHyphen = '\u2056'; contextInfo.wchVisiNonReqHyphen = '\u2057'; contextInfo.wchVisiTab = '\u2058'; contextInfo.wchVisiPosTab = contextInfo.wchUndef; contextInfo.wchVisiEmSpace = '\u2059'; contextInfo.wchVisiEnSpace = '\u205A'; contextInfo.wchVisiNarrowSpace = '\u205B'; contextInfo.wchVisiOptBreak = '\u205C'; contextInfo.wchVisiNoBreak = '\u205D'; contextInfo.wchVisiFESpace = '\u205E'; contextInfo.wchFESpace = '\u3000'; contextInfo.wchEscAnmRun = TextStore.CharParaSeparator; contextInfo.wchAltEndPara = contextInfo.wchUndef; contextInfo.wchEndLineInPara = TextStore.CharLineSeparator; contextInfo.wchSectionBreak = contextInfo.wchUndef; contextInfo.wchNonBreakSpace = '\u00A0'; contextInfo.wchNoBreak = contextInfo.wchUndef; contextInfo.wchColumnBreak = contextInfo.wchUndef; contextInfo.wchPageBreak = contextInfo.wchUndef; contextInfo.wchOptBreak = contextInfo.wchUndef; contextInfo.wchToReplace = contextInfo.wchUndef; contextInfo.wchReplace = contextInfo.wchUndef; IntPtr ploc = IntPtr.Zero; IntPtr ppenaltyModule = IntPtr.Zero; lserr = UnsafeNativeMethods.LoCreateContext( ref contextInfo, ref lscbkRedef, out ploc ); if (lserr != LsErr.None) { ThrowExceptionFromLsError(SR.Get(SRID.CreateContextFailure, lserr), lserr); } if (_specialCharacters == null) { SetSpecialCharacters(ref contextInfo); } _ploc.Value = ploc; GC.KeepAlive(contextInfo); // There is a trick here to pass in this resolution as in twips // (1/1440 an inch). // // LSCreateLine assumes the max width passed in is in twips so to // allow its client to express their width in page unit. However // it asks client to set up the real device resolution here so // that it can internally translate the "twips" width into client // actual device unit. // // We are not device dependent anyway, so instead of following the // rule which will cause us to validate the context every time. We // choose to cheat LS to think that our unit is twips. // LsDevRes devRes; devRes.dxpInch = devRes.dxrInch = TwipsPerInch; devRes.dypInch = devRes.dyrInch = TwipsPerInch; SetDoc( true, // Yes, we will be displaying true, // Yes, reference and presentation are the same device ref devRes // Device resolutions ); SetBreaking(BreakStrategies.BreakCJK); } }
protected virtual void AddText(string childText) { throw new InvalidOperationException(SR.Get(SRID.Animation_NoTextChildren)); }
/// <summary> /// Viewport3DVisual does not yet support Geometry hit testing. /// </summary> protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters) { throw new NotSupportedException(SR.Get(SRID.HitTest_Invalid, typeof(GeometryHitTestParameters).Name, this.GetType().Name)); }
/// <summary> /// Throw unexpected token exception /// </summary> private void ThrowBadToken() { throw new System.FormatException(SR.Get(SRID.Parser_UnexpectedToken, _pathString, _curIndex - 1)); }
/// <summary> /// Sets a back buffer source for this D3DImage. /// /// If enableSoftwareFallback is true, D3DImage will enable rendering of your surface /// in software (TS, etc.). /// /// You can only call this while locked. You only need to call this once, unless /// IsFrontBufferAvailable goes from false -> true and then you MUST call this /// again. When IsFrontBufferAvailable goes to false, we release our reference /// to your back buffer, except when enableSoftwareFallBack is true, in which case /// you are responsible for calling SetBackBuffer again with a null value to get us /// to release the reference. In this case, you are responsible for checking your /// device for device loss when rendering. /// /// Requirements on backBuffer by type: /// IDirect3DSurface9 /// D3DFMT_A8R8G8B8 or D3DFMT_X8R8G8B8 /// D3DUSAGE_RENDERTARGET /// D3DPOOL_DEFAULT /// Multisampling is allowed on 9Ex only /// Lockability is optional but has performance impact (see below) /// /// For best performance by type: /// IDirect3DSurface9 /// Vista WDDM: non-lockable, created on IDirect3DDevice9Ex with /// D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES and /// D3DCAPS2_CANSHARERESOURCE support. /// Vista XDDM: Doesn't matter. Software copying is fastest. /// non-Vista: Lockable with GetDC support for the pixel format and /// D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES support. /// /// </summary> public void SetBackBuffer(D3DResourceType backBufferType, IntPtr backBuffer, bool enableSoftwareFallback) { WritePreamble(); if (_lockCount == 0) { throw new InvalidOperationException(SR.Get(SRID.Image_MustBeLocked)); } // In case the user passed in something like "(D3DResourceType)-1" if (backBufferType != D3DResourceType.IDirect3DSurface9) { throw new ArgumentOutOfRangeException("backBufferType"); } // Early-out if the current back buffer equals the new one. If the front buffer // is not available and software fallback is not enabled, _pUserSurfaceUnsafe // will be null and this check will fail. We don't want a null backBuffer to // early-out when the front buffer isn't available. if (backBuffer != IntPtr.Zero && backBuffer == _pUserSurfaceUnsafe) { return; } SafeMILHandle newBitmap = null; uint newPixelWidth = 0; uint newPixelHeight = 0; // Create a new CInteropDeviceBitmap. Note that a null backBuffer will result // in a null _pInteropDeviceBitmap at the end if (backBuffer != IntPtr.Zero) { HRESULT.Check(UnsafeNativeMethods.InteropDeviceBitmap.Create( backBuffer, _dpiX, _dpiY, ++_version, _availableCallback, enableSoftwareFallback, out newBitmap, out newPixelWidth, out newPixelHeight )); } // // We need to completely disassociate with the old interop bitmap if it // exists because it won't be deleted until the composition thread is done // with it or until the garbage collector runs. // if (_pInteropDeviceBitmap != null) { // 1. Tell the old bitmap to stop sending front buffer messages because // our new back buffer may be on a different adapter. Plus, tell the // bitmap to release the back buffer in case the user wants to delete // it immediately. UnsafeNativeMethods.InteropDeviceBitmap.Detach(_pInteropDeviceBitmap); // 2. If we were waiting for a present, unhook from commit UnsubscribeFromCommittingBatch(); // 3. We are no longer dirty _isDirty = false; // Note: We don't need to do anything to the event because we're under // the protection of Lock } // If anything about the new surface were unacceptible, we would have recieved // a bad HRESULT from Create() so everything must be good _pInteropDeviceBitmap = newBitmap; _pUserSurfaceUnsafe = backBuffer; _pixelWidth = newPixelWidth; _pixelHeight = newPixelHeight; _isSoftwareFallbackEnabled = enableSoftwareFallback; // AddDirtyRect is usually what triggers Changed, but AddDirtyRect isn't allowed with // no back buffer so we mark for Changed here if (_pInteropDeviceBitmap == null) { _isChangePending = true; } RegisterForAsyncUpdateResource(); _waitingForUpdateResourceBecauseBitmapChanged = true; // WritePostscript will happen at Unlock }
/// <summary> /// Subtract operator - substracts each channel of the second color from each channel of the /// first and returns the result /// </summary> /// <param name='color1'>The minuend</param> /// <param name='color2'>The subtrahend</param> /// <returns>Returns the unclamped differnce</returns> public static Color operator -(Color color1, Color color2) { if (color1.context == null && color2.context == null) { Color c1 = FromScRgb( color1.scRgbColor.a - color2.scRgbColor.a, color1.scRgbColor.r - color2.scRgbColor.r, color1.scRgbColor.g - color2.scRgbColor.g, color1.scRgbColor.b - color2.scRgbColor.b ); return(c1); } else if (color1.context == null || color2.context == null) { throw new ArgumentException(SR.Get(SRID.Color_ColorContextTypeMismatch, null)); } else if (color1.context == color2.context) { Color c1 = new Color(); c1.context = color1.context; #pragma warning suppress 6506 // c1.context is obviously not null - both color1.context AND color2.context are not null c1.nativeColorValue = new float[c1.context.NumChannels]; for (int i = 0; i < c1.nativeColorValue.GetLength(0); i++) { c1.nativeColorValue[i] = color1.nativeColorValue[i] - color2.nativeColorValue[i]; } Color c2 = Color.FromRgb(0, 0, 0); c2.context = new ColorContext(PixelFormats.Bgra32); ColorTransform colorTransform = new ColorTransform(c1.context, c2.context); float[] sRGBValue = new float[3]; colorTransform.Translate(c1.nativeColorValue, sRGBValue); if (sRGBValue[0] < 0.0f) { c1.sRgbColor.r = 0; } else if (sRGBValue[0] > 1.0f) { c1.sRgbColor.r = 255; } else { c1.sRgbColor.r = (byte)((sRGBValue[0] * 255.0f) + 0.5f); } if (sRGBValue[1] < 0.0f) { c1.sRgbColor.g = 0; } else if (sRGBValue[1] > 1.0f) { c1.sRgbColor.g = 255; } else { c1.sRgbColor.g = (byte)((sRGBValue[1] * 255.0f) + 0.5f); } if (sRGBValue[2] < 0.0f) { c1.sRgbColor.b = 0; } else if (sRGBValue[2] > 1.0f) { c1.sRgbColor.b = 255; } else { c1.sRgbColor.b = (byte)((sRGBValue[2] * 255.0f) + 0.5f); } c1.scRgbColor.r = sRgbToScRgb(c1.sRgbColor.r); c1.scRgbColor.g = sRgbToScRgb(c1.sRgbColor.g); c1.scRgbColor.b = sRgbToScRgb(c1.sRgbColor.b); c1.scRgbColor.a = color1.scRgbColor.a - color2.scRgbColor.a; if (c1.scRgbColor.a < 0.0f) { c1.scRgbColor.a = 0.0f; c1.sRgbColor.a = 0; } else if (c1.scRgbColor.a > 1.0f) { c1.scRgbColor.a = 1.0f; c1.sRgbColor.a = 255; } else { c1.sRgbColor.a = (byte)((c1.scRgbColor.a * 255.0f) + 0.5f); } return(c1); } else { throw new ArgumentException(SR.Get(SRID.Color_ColorContextTypeMismatch, null)); } }
// NOTE: The code here is highly similar to RemoveChildCore in ModelVisual3D, // but slightly different because the parent is 2D here. void IVisual3DContainer.RemoveChild(Visual3D child) { int index = child.ParentIndex; // It is invalid to modify the children collection that we // might be iterating during a property invalidation tree walk. if (IsVisualChildrenIterationInProgress) { throw new InvalidOperationException(SR.Get(SRID.CannotModifyVisualChildrenDuringTreeWalk)); } // invalid during a VisualTreeChanged event VisualDiagnostics.VerifyVisualTreeChange(this); Debug.Assert(child != null); Debug.Assert(child.InternalVisualParent == this); VisualDiagnostics.OnVisualChildChanged(this, child, false); child.SetParent(/* newParent = */ (Visual)null); // CS0121: Call is ambigious without casting null to Visual. // remove the inheritance context if (_inheritanceContextForChildren != null) { _inheritanceContextForChildren.RemoveSelfAsInheritanceContext(child, null); } // // Remove the child on all channels this visual is marshalled to. // for (int i = 0, limit = _proxy3D.Count; i < limit; i++) { DUCE.Channel channel = _proxy3D.GetChannel(i); if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent)) { child.SetFlags(channel, false, VisualProxyFlags.IsConnectedToParent); DUCE.IResource childResource = (DUCE.IResource)child; childResource.RemoveChildFromParent(this, channel); childResource.ReleaseOnChannel(channel); } } SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty); // // Force a full precompute and render pass for this visual. // Visual.PropagateFlags( this, VisualFlags.IsSubtreeDirtyForPrecompute, VisualProxyFlags.IsSubtreeDirtyForRender); // We do not currently support layout in 3D // UIElement.PropagateSuspendLayout(child); child.FireOnVisualParentChanged(this); OnVisualChildrenChanged(/* visualAdded = */ null, child); }
private const int BUFFERSIZE = 4096; // the maximum size of the buffer used for loading from stream private void LegacyLoadFromStream(Stream cursorStream) { //Generate a temporal file based on the memory stream. // GetTempFileName requires unrestricted Environment permission // FileIOPermission.Write permission. However, since we don't // know the path of the file to be created we have to give // unrestricted permission here. // GetTempFileName documentation does not mention that it throws // any exception. However, if it does, CLR reverts the assert. string filePath = Path.GetTempFileName(); try { using (BinaryReader reader = new BinaryReader(cursorStream)) { using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Write, FileShare.None)) { // Read the bytes from the stream, up to BUFFERSIZE byte[] cursorData = reader.ReadBytes(BUFFERSIZE); int dataSize; // If the buffer is filled up, then write those bytes out and read more bytes up to BUFFERSIZE for (dataSize = cursorData.Length; dataSize >= BUFFERSIZE; dataSize = reader.Read(cursorData, 0 /*index in array*/, BUFFERSIZE /*bytes to read*/)) { fileStream.Write(cursorData, 0 /*index in array*/, BUFFERSIZE /*bytes to write*/); } // Write any remaining bytes fileStream.Write(cursorData, 0 /*index in array*/, dataSize /*bytes to write*/); } } // This method is called with File Write permission still asserted. // However, this method just reads this file into an icon. _cursorHandle = UnsafeNativeMethods.LoadImageCursor(IntPtr.Zero, filePath, NativeMethods.IMAGE_CURSOR, 0, 0, NativeMethods.LR_DEFAULTCOLOR | NativeMethods.LR_LOADFROMFILE | (_scaleWithDpi? NativeMethods.LR_DEFAULTSIZE : 0x0000)); if (_cursorHandle == null || _cursorHandle.IsInvalid) { throw new ArgumentException(SR.Get(SRID.Cursor_InvalidStream)); } } finally { try { File.Delete(filePath); } catch (System.IO.IOException) { // We may not be able to delete the file if it's being used by some other process (e.g. Anti-virus check). // There's nothing we can do in that case, so just eat the exception and leave the file behind } } }
internal static IList <TextBreakpoint> CreateMultiple( TextParagraphCache paragraphCache, int firstCharIndex, int maxLineWidth, TextLineBreak previousLineBreak, IntPtr penaltyRestriction, out int bestFitIndex ) { Invariant.Assert(paragraphCache != null); // grab full text state from paragraph cache FullTextState fullText = paragraphCache.FullText; Invariant.Assert(fullText != null); FormatSettings settings = fullText.TextStore.Settings; Invariant.Assert(settings != null); // update formatting parameters at line start settings.UpdateSettingsForCurrentLine( maxLineWidth, previousLineBreak, (firstCharIndex == fullText.TextStore.CpFirst) ); Invariant.Assert(settings.Formatter != null); // acquiring LS context TextFormatterContext context = settings.Formatter.AcquireContext(fullText, IntPtr.Zero); IntPtr previousBreakRecord = IntPtr.Zero; if (settings.PreviousLineBreak != null) { previousBreakRecord = settings.PreviousLineBreak.BreakRecord.Value; } // need not consider marker as tab since marker does not affect line metrics and it wasnt drawn. fullText.SetTabs(context); LsBreaks lsbreaks = new LsBreaks(); LsErr lserr = context.CreateBreaks( fullText.GetBreakpointInternalCp(firstCharIndex), previousBreakRecord, paragraphCache.Ploparabreak.Value, // para breaking session penaltyRestriction, ref lsbreaks, out bestFitIndex ); // get the exception in context before it is released Exception callbackException = context.CallbackException; // release the context context.Release(); if (lserr != LsErr.None) { if (callbackException != null) { // rethrow exception thrown in callbacks throw callbackException; } else { // throw with LS error codes TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.CreateBreaksFailure, lserr), lserr); } } // keep context alive at least till here GC.KeepAlive(context); TextBreakpoint[] breakpoints = new TextBreakpoint[lsbreaks.cBreaks]; for (int i = 0; i < lsbreaks.cBreaks; i++) { breakpoints[i] = new FullTextBreakpoint( fullText, firstCharIndex, maxLineWidth, ref lsbreaks, i // the current break ); } return(breakpoints); }
/// <summary> /// Verify all text formatting arguments /// </summary> private void VerifyTextFormattingArguments( TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextRunCache textRunCache ) { if (textSource == null) { throw new ArgumentNullException("textSource"); } if (textRunCache == null) { throw new ArgumentNullException("textRunCache"); } if (paragraphProperties == null) { throw new ArgumentNullException("paragraphProperties"); } if (paragraphProperties.DefaultTextRunProperties == null) { throw new ArgumentNullException("paragraphProperties.DefaultTextRunProperties"); } if (paragraphProperties.DefaultTextRunProperties.Typeface == null) { throw new ArgumentNullException("paragraphProperties.DefaultTextRunProperties.Typeface"); } if (DoubleUtil.IsNaN(paragraphWidth)) { throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterValueCannotBeNaN)); } if (double.IsInfinity(paragraphWidth)) { throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterValueCannotBeInfinity)); } if (paragraphWidth < 0 || paragraphWidth > Constants.RealInfiniteWidth) { throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterMustBeBetween, 0, Constants.RealInfiniteWidth)); } double realMaxFontRenderingEmSize = Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm; if (paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize < 0 || paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize > realMaxFontRenderingEmSize) { throw new ArgumentOutOfRangeException("paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize", SR.Get(SRID.ParameterMustBeBetween, 0, realMaxFontRenderingEmSize)); } if (paragraphProperties.Indent > Constants.RealInfiniteWidth) { throw new ArgumentOutOfRangeException("paragraphProperties.Indent", SR.Get(SRID.ParameterCannotBeGreaterThan, Constants.RealInfiniteWidth)); } if (paragraphProperties.LineHeight > Constants.RealInfiniteWidth) { throw new ArgumentOutOfRangeException("paragraphProperties.LineHeight", SR.Get(SRID.ParameterCannotBeGreaterThan, Constants.RealInfiniteWidth)); } if (paragraphProperties.DefaultIncrementalTab < 0 || paragraphProperties.DefaultIncrementalTab > Constants.RealInfiniteWidth) { throw new ArgumentOutOfRangeException("paragraphProperties.DefaultIncrementalTab", SR.Get(SRID.ParameterMustBeBetween, 0, Constants.RealInfiniteWidth)); } }
internal TextFormatterContext AcquireContext( object owner, IntPtr ploc ) { Invariant.Assert(owner != null); TextFormatterContext context = null; int c; int contextCount = _contextList.Count; for (c = 0; c < contextCount; c++) { context = (TextFormatterContext)_contextList[c]; if (ploc == IntPtr.Zero) { if (context.Owner == null) { break; } } else if (ploc == context.Ploc.Value) { // LS requires that we use the exact same context for line // destruction or hittesting (part of the reason is that LS // actually caches some run info in the context). So here // we use the actual PLSC as the context signature so we // locate the one we want. Debug.Assert(context.Owner == null); break; } } if (c == contextCount) { if (contextCount == 0 || !_multipleContextProhibited) { // no free one exists, create a new one context = new TextFormatterContext(); _contextList.Add(context); } else { // This instance of TextFormatter only allows a single context, reentering the // same TextFormatter in this case is not allowed. // // This requirement is currently enforced only during optimal break computation. // Client implementing nesting of optimal break content inside another must create // a separate TextFormatter instance for each content in different nesting level. throw new InvalidOperationException(SR.Get(SRID.TextFormatterReentranceProhibited)); } } Debug.Assert(context != null); context.Owner = owner; return(context); }
/// <summary> /// Removes a handler for the SourceChanged event to the element. /// </summary> /// <param name="e">The element to remove the handler from.</param> /// <param name="handler">The hander to remove.</param> /// <remarks> /// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement RemoveHandler() method. /// </remarks> public static void RemoveSourceChangedHandler(IInputElement e, SourceChangedEventHandler handler) { if (e == null) { throw new ArgumentNullException("e"); } if (!InputElement.IsValid(e)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "e"); } DependencyObject o = (DependencyObject)e; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectList <RoutedEventHandlerInfo> info = null; EventHandlersStore store; // Either UIElement or ContentElement. if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.RemoveHandler(SourceChangedEvent, handler); store = uie.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged);; RemoveElementFromWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.RemoveHandler(SourceChangedEvent, handler); store = uie3D.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie3D.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged);; RemoveElementFromWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.RemoveHandler(SourceChangedEvent, handler); store = ce.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { RemoveElementFromWatchList(ce); } } } }
/// <summary> /// Recognize the strokes. /// </summary> /// <param name="strokes"></param> /// <returns></returns> internal GestureRecognitionResult[] Recognize(StrokeCollection strokes) { if (_disposed) { throw new ObjectDisposedException("NativeRecognizer"); } // // note that we validate this argument from GestureRecognizer // but since this is marked TAS, we want to do it here as well // if (strokes == null) { throw new ArgumentNullException("strokes"); // Null is not allowed as the argument value } if (strokes.Count > 2) { throw new ArgumentException(SR.Get(SRID.StrokeCollectionCountTooBig), "strokes"); } // Create an empty result. GestureRecognitionResult[] recResults = new GestureRecognitionResult[] {}; if (strokes.Count == 0) { return(recResults); } int hr = 0; try { // Reset the context hr = MS.Win32.Recognizer.UnsafeNativeMethods.ResetContext(_hContext); if (HRESULT.Failed(hr)) { //finally block will clean up and throw return(recResults); } // Add strokes hr = AddStrokes(_hContext, strokes); if (HRESULT.Failed(hr)) { //AddStrokes's finally block will clean up this finally block will throw return(recResults); } // recognize the ink bool bIncremental; hr = MS.Win32.Recognizer.UnsafeNativeMethods.Process(_hContext, out bIncremental); if (HRESULT.Succeeded(hr)) { if (s_GetAlternateListExists) { recResults = InvokeGetAlternateList(); } else { recResults = InvokeGetLatticePtr(); } } } finally { // Check if we should report any error. if (HRESULT.Failed(hr)) { //don't throw a com exception here, we don't need to pass out any details throw new InvalidOperationException(SR.Get(SRID.UnspecifiedGestureException)); } } return(recResults); }
// // /// <summary> // /// See if the current token matches the string s. If so, advance and // /// return true. Else, return false. // /// </summary> // bool TryAdvance(string s) // { // Debug.Assert(s.Length != 0); // // bool match = false; // if (More() && _pathString[_currentIndex] == s[0]) // { // // // // Don't bother reading subsequent characters, as the CLR parser will // // do this for us later. // // // _currentIndex = Math.Min(_currentIndex + s.Length, _pathLength); // // match = true; // } // // return match; // } // /// <summary> /// Read a floating point number /// </summary> /// <returns></returns> double ReadNumber(bool allowComma) { if (!IsNumber(allowComma)) { ThrowBadToken(); } bool simple = true; int start = _curIndex; // // Allow for a sign // // There are numbers that cannot be preceded with a sign, for instance, -NaN, but it's // fine to ignore that at this point, since the CLR parser will catch this later. // if (More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+')) { _curIndex++; } // Check for Infinity (or -Infinity). if (More() && (_pathString[_curIndex] == 'I')) { // // Don't bother reading the characters, as the CLR parser will // do this for us later. // _curIndex = Math.Min(_curIndex + 8, _pathLength); // "Infinity" has 8 characters simple = false; } // Check for NaN else if (More() && (_pathString[_curIndex] == 'N')) { // // Don't bother reading the characters, as the CLR parser will // do this for us later. // _curIndex = Math.Min(_curIndex + 3, _pathLength); // "NaN" has 3 characters simple = false; } else { SkipDigits(!AllowSign); // Optional period, followed by more digits if (More() && (_pathString[_curIndex] == '.')) { simple = false; _curIndex++; SkipDigits(!AllowSign); } // Exponent if (More() && ((_pathString[_curIndex] == 'E') || (_pathString[_curIndex] == 'e'))) { simple = false; _curIndex++; SkipDigits(AllowSign); } } if (simple && (_curIndex <= (start + 8))) // 32-bit integer { int sign = 1; if (_pathString[start] == '+') { start++; } else if (_pathString[start] == '-') { start++; sign = -1; } int value = 0; while (start < _curIndex) { value = value * 10 + (_pathString[start] - '0'); start++; } return(value * sign); } else { ReadOnlySpan <char> slice = _pathString.AsSpan(start, _curIndex - start); try { return(double.Parse(slice, provider: _formatProvider)); } catch (FormatException except) { throw new System.FormatException(SR.Get(SRID.Parser_UnexpectedToken, _pathString, start), except); } } }
internal static ApplicationGesture[] GetApplicationGestureArrayAndVerify(IEnumerable <ApplicationGesture> applicationGestures) { if (applicationGestures == null) { // Null is not allowed as the argument value throw new ArgumentNullException("applicationGestures"); } uint count = 0; //we need to make a disconnected copy ICollection <ApplicationGesture> collection = applicationGestures as ICollection <ApplicationGesture>; if (collection != null) { count = (uint)collection.Count; } else { foreach (ApplicationGesture gesture in applicationGestures) { count++; } } // Cannot be empty if (count == 0) { // An empty array is not allowed. throw new ArgumentException(SR.Get(SRID.ApplicationGestureArrayLengthIsZero), "applicationGestures"); } bool foundAllGestures = false; List <ApplicationGesture> gestures = new List <ApplicationGesture>(); foreach (ApplicationGesture gesture in applicationGestures) { if (!ApplicationGestureHelper.IsDefined(gesture)) { throw new ArgumentException(SR.Get(SRID.ApplicationGestureIsInvalid), "applicationGestures"); } //check for allgestures if (gesture == ApplicationGesture.AllGestures) { foundAllGestures = true; } //check for dupes if (gestures.Contains(gesture)) { throw new ArgumentException(SR.Get(SRID.DuplicateApplicationGestureFound), "applicationGestures"); } gestures.Add(gesture); } // AllGesture cannot be specified with other gestures if (foundAllGestures && gestures.Count != 1) { // no dupes allowed throw new ArgumentException(SR.Get(SRID.AllGesturesMustExistAlone), "applicationGestures"); } return(gestures.ToArray()); }
/// <summary> /// Captures the stylus to a particular element. /// </summary> internal override bool Capture(IInputElement element, CaptureMode captureMode) { int timeStamp = Environment.TickCount; VerifyAccess(); if (!(captureMode == CaptureMode.None || captureMode == CaptureMode.Element || captureMode == CaptureMode.SubTree)) { throw new System.ComponentModel.InvalidEnumArgumentException("captureMode", (int)captureMode, typeof(CaptureMode)); } if (element == null) { captureMode = CaptureMode.None; } if (captureMode == CaptureMode.None) { element = null; } // Validate that element is either a UIElement or a ContentElement DependencyObject doStylusCapture = element as DependencyObject; if (doStylusCapture != null && !InputElement.IsValid(element)) { throw new InvalidOperationException(SR.Get(SRID.Invalid_IInputElement, doStylusCapture.GetType())); } doStylusCapture?.VerifyAccess(); bool success = false; // The element we are capturing to must be both enabled and visible. UIElement e = element as UIElement; if ((e?.IsVisible ?? false) || (e?.IsEnabled ?? false)) { success = true; } else { ContentElement ce = element as ContentElement; if (ce?.IsEnabled ?? false) { success = true; } else { // Setting capture to null. success = true; } } if (success) { ChangeStylusCapture(element, captureMode, timeStamp); } return(success); }
/// <summary> /// Replaces any instances of the sentinal brush with the internal brush /// </summary> /// <param name="material">The material to look through</param> private void SwapInCyclicBrush(Material material) { int numMaterialsSwapped = 0; Stack <Material> materialStack = new Stack <Material>(); materialStack.Push(material); Brush internalBrush = (CacheMode as BitmapCache != null) ? (Brush)InternalBitmapCacheBrush : (Brush)InternalVisualBrush; while (materialStack.Count > 0) { Material currMaterial = materialStack.Pop(); if (currMaterial is DiffuseMaterial) { DiffuseMaterial diffMaterial = (DiffuseMaterial)currMaterial; if ((Boolean)diffMaterial.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { diffMaterial.Brush = internalBrush; numMaterialsSwapped++; } } else if (currMaterial is EmissiveMaterial) { EmissiveMaterial emmMaterial = (EmissiveMaterial)currMaterial; if ((Boolean)emmMaterial.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { emmMaterial.Brush = internalBrush; numMaterialsSwapped++; } } else if (currMaterial is SpecularMaterial) { SpecularMaterial specMaterial = (SpecularMaterial)currMaterial; if ((Boolean)specMaterial.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { specMaterial.Brush = internalBrush; numMaterialsSwapped++; } } else if (currMaterial is MaterialGroup) { MaterialGroup matGroup = (MaterialGroup)currMaterial; // the IsVisualHostMaterialProperty should not be set on a MaterialGroup - verify that if ((Boolean)matGroup.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { throw new ArgumentException(SR.Get(SRID.Viewport2DVisual3D_MaterialGroupIsInteractiveMaterial), "material"); } // iterate over the children and put them on the stack of materials to modify MaterialCollection children = matGroup.Children; if (children != null) { for (int i = 0, count = children.Count; i < count; i++) { Material m = children[i]; materialStack.Push(m); } } } else { Invariant.Assert(true, "Unexpected Material type encountered. V2DV3D handles DiffuseMaterial, EmissiveMaterial, SpecularMaterial, and MaterialGroup."); } } // throw if there is more than 1 interactive material if (numMaterialsSwapped > 1) { throw new ArgumentException(SR.Get(SRID.Viewport2DVisual3D_MultipleInteractiveMaterials), "material"); } }
internal static void BeginDownload( BitmapDecoder decoder, Uri uri, RequestCachePolicy uriCachePolicy, Stream stream ) { lock (_syncLock) { if (!_thread.IsAlive) { _thread.IsBackground = true; _thread.Start(); } } QueueEntry entry; // If there is already a download for this uri, just add the decoder to the list if (uri != null) { lock (_syncLock) { if (_uriTable[uri] != null) { entry = (QueueEntry)_uriTable[uri]; entry.decoders.Add(new WeakReference(decoder)); return; } } } entry = new QueueEntry(); entry.decoders = new List <WeakReference>(); lock (_syncLock) { entry.decoders.Add(new WeakReference(decoder)); } entry.inputUri = uri; entry.inputStream = stream; string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath; bool passed = false; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert try { // Get the file path StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH); MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName); try { string pathToUse = tmpFileName.ToString(); SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile( pathToUse, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */ 0, /* dwShare */ null, /* lpSecurityAttributes */ NativeMethods.CREATE_ALWAYS, /* dwCreationDisposition */ NativeMethods.FILE_ATTRIBUTE_TEMPORARY | NativeMethods.FILE_FLAG_DELETE_ON_CLOSE, /* dwFlagsAndAttributes */ IntPtr.Zero /* hTemplateFile */ ); if (fileHandle.IsInvalid) { throw new Win32Exception(); } entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite); entry.streamPath = pathToUse; passed = true; } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e)) { throw; } } } finally { SecurityPermission.RevertAssert(); } if (!passed) { throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile)); } entry.readBuffer = new byte[READ_SIZE]; entry.contentLength = -1; entry.contentType = string.Empty; entry.lastPercent = 0; // Add the entry to the table if we know the uri if (uri != null) { lock (_syncLock) { _uriTable[uri] = entry; } } if (stream == null) { bool fElevate = false; if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) { SecurityHelper.BlockCrossDomainForHttpsApps(uri); // In this case we first check to see if the consumer has media permissions for // safe media (Site of Origin + Cross domain), if it // does we assert and run the code that requires the assert if (SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.NoAudio, MediaPermissionVideo.NoVideo, MediaPermissionImage.SafeImage)) { fElevate = true; } } // This is the case where we are accessing an http image from an http site and we have media permission if (fElevate) { (new WebPermission(NetworkAccess.Connect, BindUriHelper.UriToString(uri))).Assert(); // BlessedAssert } try { entry.webRequest = WpfWebRequestHelper.CreateRequest(uri); if (uriCachePolicy != null) { entry.webRequest.CachePolicy = uriCachePolicy; } } finally { if (fElevate) { WebPermission.RevertAssert(); } } entry.webRequest.BeginGetResponse(_responseCallback, entry); } else { _workQueue.Enqueue(entry); // Signal _waitEvent.Set(); } }
/// <summary> /// Derived class must implement to support Visual children. The method must return /// the child at the specified index. Index must be between 0 and GetVisualChildrenCount-1. /// /// By default a Visual3D does not have any children. /// /// Remark: /// Need to lock down Visual tree during the callbacks. /// During this virtual call it is not valid to modify the Visual tree. /// /// It is okay to type this protected API to the 2D Visual. The only 2D Visual with /// 3D childern is the Viewport3DVisual which is sealed. -- [....] 01/17/06 /// </summary> protected override Visual3D GetVisual3DChild(int index) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); }
/// <summary> /// Creates a TransformCollection with all of the same elements as collection /// </summary> public TransformCollection(IEnumerable <Transform> collection) { // The WritePreamble and WritePostscript aren't technically necessary // in the constructor as of 1/20/05 but they are put here in case // their behavior changes at a later date WritePreamble(); if (collection != null) { bool needsItemValidation = true; ICollection <Transform> icollectionOfT = collection as ICollection <Transform>; if (icollectionOfT != null) { _collection = new FrugalStructList <Transform>(icollectionOfT); } else { ICollection icollection = collection as ICollection; if (icollection != null) // an IC but not and IC<T> { _collection = new FrugalStructList <Transform>(icollection); } else // not a IC or IC<T> so fall back to the slower Add { _collection = new FrugalStructList <Transform>(); foreach (Transform item in collection) { if (item == null) { throw new System.ArgumentException(SR.Get(SRID.Collection_NoNull)); } Transform newValue = item; OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); OnInsert(newValue); } needsItemValidation = false; } } if (needsItemValidation) { foreach (Transform item in collection) { if (item == null) { throw new System.ArgumentException(SR.Get(SRID.Collection_NoNull)); } OnFreezablePropertyChanged(/* oldValue = */ null, item); OnInsert(item); } } WritePostscript(); } else { throw new ArgumentNullException("collection"); } }
/// /// Begin a download /// internal static void BeginDownload( BitmapDecoder decoder, Uri uri, RequestCachePolicy uriCachePolicy, Stream stream ) { lock (_syncLock) { if (!_thread.IsAlive) { _thread.IsBackground = true; _thread.Start(); } } QueueEntry entry; // If there is already a download for this uri, just add the decoder to the list if (uri != null) { lock (_syncLock) { if (_uriTable[uri] != null) { entry = (QueueEntry)_uriTable[uri]; entry.decoders.Add(new WeakReference(decoder)); return; } } } entry = new QueueEntry(); entry.decoders = new List <WeakReference>(); lock (_syncLock) { entry.decoders.Add(new WeakReference(decoder)); } entry.inputUri = uri; entry.inputStream = stream; string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath; bool passed = false; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert try { // Get the file path StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH); MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName); try { string pathToUse = tmpFileName.ToString(); SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile( pathToUse, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */ 0, /* dwShare */ null, /* lpSecurityAttributes */ NativeMethods.CREATE_ALWAYS, /* dwCreationDisposition */ NativeMethods.FILE_ATTRIBUTE_TEMPORARY | NativeMethods.FILE_FLAG_DELETE_ON_CLOSE, /* dwFlagsAndAttributes */ IntPtr.Zero /* hTemplateFile */ ); if (fileHandle.IsInvalid) { throw new Win32Exception(); } entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite); entry.streamPath = pathToUse; passed = true; } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e)) { throw; } } } finally { SecurityPermission.RevertAssert(); } if (!passed) { throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile)); } entry.readBuffer = new byte[READ_SIZE]; entry.contentLength = -1; entry.contentType = string.Empty; entry.lastPercent = 0; // Add the entry to the table if we know the uri if (uri != null) { lock (_syncLock) { _uriTable[uri] = entry; } } if (stream == null) { entry.webRequest = WpfWebRequestHelper.CreateRequest(uri); if (uriCachePolicy != null) { entry.webRequest.CachePolicy = uriCachePolicy; } entry.webRequest.BeginGetResponse(_responseCallback, entry); } else { _workQueue.Enqueue(entry); // Signal _waitEvent.Set(); } }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); Uri uri = UriSource; if (_baseUri != null) { uri = new Uri(_baseUri, UriSource); } if ((CreateOptions & BitmapCreateOptions.IgnoreImageCache) != 0) { ImagingCache.RemoveFromImageCache(uri); } BitmapImage bitmapImage = CheckCache(uri); if (bitmapImage != null && bitmapImage.CheckAccess() && bitmapImage.SourceRect.Equals(SourceRect) && bitmapImage.DecodePixelWidth == DecodePixelWidth && bitmapImage.DecodePixelHeight == DecodePixelHeight && bitmapImage.Rotation == Rotation && (bitmapImage.CreateOptions & BitmapCreateOptions.IgnoreColorProfile) == (CreateOptions & BitmapCreateOptions.IgnoreColorProfile) ) { _syncObject = bitmapImage.SyncObject; lock (_syncObject) { WicSourceHandle = bitmapImage.WicSourceHandle; IsSourceCached = bitmapImage.IsSourceCached; _convertedDUCEPtr = bitmapImage._convertedDUCEPtr; // // We nee d to keep the strong reference to the cached image for a few reasons: // // The application may release the original cached image and then keep a // reference to this image only, in which case, the cache can be collected. // This will cause a few undesirable results: // 1. The application may choose to decode the same URI again in which case // we will not retrieve it from the cache even though we have a copy already // decoded. // 2. The original cached image holds onto the file stream indirectly which if // collected can cause bad behavior if the entire image is not loaded into // memory. // _cachedBitmapImage = bitmapImage; } UpdateCachedSettings(); return; } BitmapDecoder decoder = null; if (_decoder == null) { // Note: We do not want to insert in the cache if there is a chance that // the decode pixel width/height may cause the decoder LOD to change decoder = BitmapDecoder.CreateFromUriOrStream( _baseUri, UriSource, StreamSource, CreateOptions & ~BitmapCreateOptions.DelayCreation, BitmapCacheOption.None, // do not cache the frames since we will do that here _uriCachePolicy, false ); if (decoder.IsDownloading) { _isDownloading = true; _decoder = decoder; decoder.DownloadProgress += OnDownloadProgress; decoder.DownloadCompleted += OnDownloadCompleted; decoder.DownloadFailed += OnDownloadFailed; } else { Debug.Assert(decoder.SyncObject != null); } } else { // We already had a decoder, meaning we were downloading Debug.Assert(!_decoder.IsDownloading); decoder = _decoder; _decoder = null; } if (decoder.Frames.Count == 0) { throw new System.ArgumentException(SR.Get(SRID.Image_NoDecodeFrames)); } BitmapFrame frame = decoder.Frames[0]; BitmapSource source = frame; Int32Rect sourceRect = SourceRect; if (sourceRect.X == 0 && sourceRect.Y == 0 && sourceRect.Width == source.PixelWidth && sourceRect.Height == source.PixelHeight) { sourceRect = Int32Rect.Empty; } if (!sourceRect.IsEmpty) { CroppedBitmap croppedSource = new CroppedBitmap(); croppedSource.BeginInit(); croppedSource.Source = source; croppedSource.SourceRect = sourceRect; croppedSource.EndInit(); source = croppedSource; if (_isDownloading) { // Unregister the download events because this is a dummy image. See comment below. source.UnregisterDownloadEventSource(); } } int finalWidth = DecodePixelWidth; int finalHeight = DecodePixelHeight; if (finalWidth == 0 && finalHeight == 0) { finalWidth = source.PixelWidth; finalHeight = source.PixelHeight; } else if (finalWidth == 0) { finalWidth = (source.PixelWidth * finalHeight) / source.PixelHeight; } else if (finalHeight == 0) { finalHeight = (source.PixelHeight * finalWidth) / source.PixelWidth; } if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight || Rotation != Rotation.Rotate0) { TransformedBitmap transformedSource = new TransformedBitmap(); transformedSource.BeginInit(); transformedSource.Source = source; TransformGroup transformGroup = new TransformGroup(); if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight) { int oldWidth = source.PixelWidth; int oldHeight = source.PixelHeight; Debug.Assert(oldWidth > 0 && oldHeight > 0); transformGroup.Children.Add( new ScaleTransform( (1.0 * finalWidth) / oldWidth, (1.0 * finalHeight) / oldHeight)); } if (Rotation != Rotation.Rotate0) { double rotation = 0.0; switch (Rotation) { case Rotation.Rotate0: rotation = 0.0; break; case Rotation.Rotate90: rotation = 90.0; break; case Rotation.Rotate180: rotation = 180.0; break; case Rotation.Rotate270: rotation = 270.0; break; default: Debug.Assert(false); break; } transformGroup.Children.Add(new RotateTransform(rotation)); } transformedSource.Transform = transformGroup; transformedSource.EndInit(); source = transformedSource; if (_isDownloading) { // // If we're currently downloading, then the BitmapFrameDecode isn't actually // the image, it's just a 1x1 placeholder. The chain we're currently building // will be replaced with another chain once download completes, so there's no // need to have this chain handle DownloadCompleted. // // Having this chain handle DownloadCompleted is actually a bad thing. Because // the dummy is just 1x1, the TransformedBitmap we're building here will have // a large scaling factor (to scale the image from 1x1 up to whatever // DecodePixelWidth/Height specifies). When the TransformedBitmap receives // DownloadCompleted from the BFD, it will call into WIC to create a new // bitmap scaler using the same large scaling factor, which can produce a huge // bitmap (since the BFD is now no longer 1x1). This problem is made worse if // this BitmapImage has BitmapCacheOption.OnLoad, since that will put a // CachedBitmap after the TransformedBitmap. When DownloadCompleted propagates // from the TransformedBitmap down to the CachedBitmap, the CachedBitmap will // call CreateBitmapFromSource using the TransformedBitmap, which calls // CopyPixels on the huge TransformedBitmap. We want to avoid chewing up the // CPU and the memory, so we unregister the download event handlers here. // source.UnregisterDownloadEventSource(); } } // // If the original image has a color profile and IgnoreColorProfile is not one of the create options, // apply the profile so bits are color-corrected. // if ((CreateOptions & BitmapCreateOptions.IgnoreColorProfile) == 0 && frame.ColorContexts != null && frame.ColorContexts[0] != null && frame.ColorContexts[0].IsValid && source.Format.Format != PixelFormatEnum.Extended ) { // NOTE: Never do this for a non-MIL pixel format, because the format converter has // special knowledge to deal with the profile PixelFormat duceFormat = BitmapSource.GetClosestDUCEFormat(source.Format, source.Palette); bool changeFormat = (source.Format != duceFormat); ColorContext destinationColorContext; // We need to make sure, we can actually create the ColorContext for the destination duceFormat // If the duceFormat is gray or scRGB, the following is not supported, so we cannot // create the ColorConvertedBitmap try { destinationColorContext = new ColorContext(duceFormat); } catch (NotSupportedException) { destinationColorContext = null; } if (destinationColorContext != null) { bool conversionSuccess = false; bool badColorContext = false; // First try if the color converter can handle the source format directly // Its possible that the color converter does not support certain pixelformats, so put a try/catch here. try { ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap( source, frame.ColorContexts[0], destinationColorContext, duceFormat ); source = colorConvertedBitmap; if (_isDownloading) { // Unregister the download events because this is a dummy image. See comment above. source.UnregisterDownloadEventSource(); } conversionSuccess = true; } catch (NotSupportedException) { } catch (FileFormatException) { // If the file contains a bad color context, we catch the exception here // and don't bother trying the color conversion below, since color transform isn't possible // with the given color context. badColorContext = true; } if (!conversionSuccess && !badColorContext && changeFormat) { // If the conversion failed, we first use // a FormatConvertedBitmap, and then Color Convert that one... FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap(source, duceFormat, source.Palette, 0.0); ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap( formatConvertedBitmap, frame.ColorContexts[0], destinationColorContext, duceFormat ); source = colorConvertedBitmap; if (_isDownloading) { // Unregister the download events because this is a dummy image. See comment above. source.UnregisterDownloadEventSource(); } } } } if (CacheOption != BitmapCacheOption.None) { try { // The bitmaps bits could be corrupt, and this will cause an exception if the CachedBitmap forces a decode. CachedBitmap cachedSource = new CachedBitmap(source, CreateOptions & ~BitmapCreateOptions.DelayCreation, CacheOption); source = cachedSource; if (_isDownloading) { // Unregister the download events because this is a dummy image. See comment above. source.UnregisterDownloadEventSource(); } } catch (Exception e) { RecoverFromDecodeFailure(e); CreationCompleted = true; // we're bailing out because the decode failed return; } } // If CacheOption == OnLoad, no need to keep the stream around if (decoder != null && CacheOption == BitmapCacheOption.OnLoad) { decoder.CloseStream(); } else if (CacheOption != BitmapCacheOption.OnLoad) { //ensure that we don't GC the source _finalSource = source; } WicSourceHandle = source.WicSourceHandle; IsSourceCached = source.IsSourceCached; CreationCompleted = true; UpdateCachedSettings(); // Only insert in the imaging cache if download is complete if (!IsDownloading) { InsertInCache(uri); } }
/// <summary> /// Open Media /// </summary> private void OpenMedia(Uri source) { string toOpen = null; if (source != null && source.IsAbsoluteUri && source.Scheme == PackUriHelper.UriSchemePack) { try { source = BaseUriHelper.ConvertPackUriToAbsoluteExternallyVisibleUri(source); } catch (InvalidOperationException) { source = null; _mediaEventsHelper.RaiseMediaFailed(new System.NotSupportedException(SR.Get(SRID.Media_PackURIsAreNotSupported, null))); } } // Setting a null source effectively disconects the MediaElement. if (source != null) { // keep whether we asserted permissions or not bool elevated = false; // get the base directory of the application; never expose this Uri appBase = SecurityHelper.GetBaseDirectory(AppDomain.CurrentDomain); // this extracts the URI to open Uri uriToOpen = ResolveUri(source, appBase); // access is allowed in the following cases (only 1 & 2 require elevation): // 1) to any HTTPS media if app is NOT coming from HTTPS // 2) to URI in the current directory of the fusion cache // 3) to site of origin media if (SecurityHelper.AreStringTypesEqual(uriToOpen.Scheme, Uri.UriSchemeHttps)) { // target is HTTPS. Then, elevate ONLY if we are NOT coming from HTTPS (=XDomain HTTPS app to HTTPS media disallowed) Uri appDeploymentUri = SecurityHelper.ExtractUriForClickOnceDeployedApp(); if (!SecurityHelper.AreStringTypesEqual(appDeploymentUri.Scheme, Uri.UriSchemeHttps)) { new WebPermission(NetworkAccess.Connect, BindUriHelper.UriToString(uriToOpen)).Assert(); elevated = true; } } else { // elevate to allow access to media in the app's directory in the fusion cache. new FileIOPermission(FileIOPermissionAccess.Read, appBase.LocalPath).Assert();// BlessedAssert elevated = true; } // demand permissions. if demands succeds, it means we are in one of the cases above. try { toOpen = DemandPermissions(uriToOpen); } finally { if (elevated) { CodeAccessPermission.RevertAssert(); } } } else { toOpen = null; } // We pass in exact same URI for which we demanded permissions so that we can be sure // there is no discrepancy between the two. HRESULT.Check(MILMedia.Open(_nativeMedia, toOpen)); }