Oreoorererereoo

Pepe, 364 bytes

Unfortunately the online interpreter does not take care of compressing comments, hence all o characters will be replaced by a space.. Neither the spaces nor the o are necessary, so this could be 295 bytes, but I like it more this way:

rEeEEeeEeEororEEoreoreeeEeeeeeorEEEEeoREeoreorEeEEeEEEEororEEoreorEEEEEoREeoreorEeEEEeeEeororEEoreoReoREoREEEeoREEEEEoreorEorEEEeorEEEEEoreEoREeoreoREEeoREEEEeEeeoREEEeoREeeEoREEEeoREEEEEEEorEEEeEorEEEeoREoREEEeoREEEEEoREEoReoreorEEEeEoREEEEEEeorEEEeoReEoREoREEEeoREEoReoroReEeoREoREEEeorEEEEeoReeoREEEeoREeeEoREEEeoREEEEEEEoreoReoReoREoREEEeoREEEEEoreeeeeEeEeoRee

Try it online!

Ungolfed

There might be some golfing oppurtunities with flags which I missed, but I'm done for now:

# "function" for 'e'
rEeEEeeEeE rrEE
  re          # remove duplicated argument
  reeeEeeeee  # print space
  rEEEEe      # decrement counter twice
REe re

# "function" for 'o'
rEeEEeEEEE rrEE
  re      # remove duplicated argument
  rEEEEE  # increment counter
REe re

# "function for 'r'
rEeEEEeeEe rrEE
  re Re              # remove duplicated argument & char
  RE REEEe REEEEE    # push 1
  re rE rEEEe rEEEEE # replace 1
  reE                # goto 1
REe re

# Main

REEe REEEEeEee                # read input & reverse
REEEe REeeE REEEe REEEEEEE    # push length-1 & move to r

rEEEeE rEEEe # dummy loop-var (fucking do-whiles...)
RE REEEe REEEEE REE  # while [label-1]

  # Call the right procedure depending on current character,
  # sets stacks up as follows:
  #   R [ .... *currentChar ]
  #   r [ (N-1) *count ]
  Re re          # pop 1 & loop-counter
  rEEEeE         # duplicate counter
  REEEEEEe rEEEe # copy current char to other stack
  ReE            # jeq to 'o'-label or 'e'-label

  # Output currentChar count times:
  RE REEEe REE # while [label-0]:
    Re         #   pop 0
    rReEe      #   print character
    RE REEEe   #   push 0
    rEEEEe     #   decrement counter
  Ree

  REEEe REeeE REEEe REEEEEEE  # push length-1 & move to r
  re Re Re                    # pop 0, counter and 9((((currentChar
  RE REEEe REEEEE             # push 1
  reeeeeEeEe                  # print new-line

Ree

Jelly,  16 14  13 bytes

-1 Thanks to Erik the Outgolfer

OḂƇẒṁ€aØ.¦€⁶Y

Uses 1 for the cream and 0 for the cookie.

Try it online!

How?

OḂƇẒṁ€aØ.¦€⁶Y - Main Link: list of characters, V    e.g. 'orereo'
O             - ordinal (vectorises)                     [111,114,101,114,101,111]
  Ƈ           - filter keep those for which:
 Ḃ            -   modulo 2                               [111,    101,    101,111]
   Ẓ          - is prime? (vectorises)                   [  0,      1,      1,  0]
    ṁ€        - mould each like V                        [[0,0,0,0,0,0],[1,1,1,1,1,1],[1,1,1,1,1,1],[0,0,0,0,0,0]]
          €   - for each:
         ¦    -   sparse application...
       Ø.     -   ...to indices: literal [0,1] (0 is the rightmost index, 1 is the leftmost)
      a       -   ...apply: logical AND with:
           ⁶  -               space character           [[0,0,0,0,0,0],[' ',1,1,1,1,' '],[' ',1,1,1,1,' '],[0,0,0,0,0,0]]
            Y - join with newline characters            [0,0,0,0,0,0,'\n',' ',1,1,1,1,' ','\n',' ',1,1,1,1,' ','\n',0,0,0,0,0,0]
              - implicit print                       ...smashes everything together:
              -                                         000000
              -                                          1111 
              -                                          1111 
              -                                         000000

Previous 16 byter:

ḟ”eẋ€Ly@Ø.¦€⁾r Y

Uses r for the cream and o for the cookie.

Try it online!


Canvas, 19 18 17 bytes

e ∙╋
:r≠*┤];L×⁸↔⁸

Try it here!

Uses the annoyingly long code of :r≠*┤] to remove rs from the input..